Initial version of donated sources by Avertec, 3.4p5.
[tas-yagle.git] / distrib / sources / mbk / mbk_lo_util.c
1 /*
2 * This file is part of the Alliance CAD System
3 * Copyright (C) Laboratoire LIP6 - Département ASIM
4 * Universite Pierre et Marie Curie
5 *
6 * Home page : http://www-asim.lip6.fr/alliance/
7 * E-mail support : mailto:alliance-support@asim.lip6.fr
8 *
9 * This library is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU Library General Public License as published
11 * by the Free Software Foundation; either version 2 of the License, or (at
12 * your option) any later version.
13 *
14 * Alliance VLSI CAD System is distributed in the hope that it will be
15 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
17 * Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with the GNU C Library; see the file COPYING. If not, write to the Free
21 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24 /*
25 * Purpose : utilities for logical structures
26 * Date : 05/11/92
27 * Author : Frederic Petrot <Frederic.Petrot@lip6.fr>
28 * Modified by Czo <Olivier.Sirol@lip6.fr> 1997,98
29 */
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <ctype.h>
34 #include <unistd.h>
35 #include <string.h>
36 #include <regex.h>
37
38 #include MUT_H
39 #include MLO_H
40 #include RCN_H
41 #include MLU_H
42 #include AVT_H
43 #include INF_H
44 #include MCC_H
45 #include MSL_H
46
47 #include "mbk_lo_util.h"
48 #include "rcn.h"
49
50 /* local for flattenlofig */
51 #define FLATTEN_CTC 19971215
52 #define FLATTEN_POSTRAIT 19971216
53
54 void debugctc (losig_list *, int);
55 void debugctc2 (lofig_list *);
56
57 static chain_list *BLACKLIST=NULL;
58 static mbk_match_rules *BLACKLIST_MATCH_RULE=NULL, *BLACKLIST_MATCH_RULE_UNUSED=NULL;
59
60 int MBK_HANDLE_GLOBAL_NODES=1;
61 int MLU_TRACE_EQT = 0;
62 lofig_list *(*HOOK_GETLOADEDLOFIG) (char *name) = NULL;
63 static int bl_loaded = 0;
64
65 /*******************************************************************************
66 * function getlofig() *
67 * if mode == 'A' all the figure is needed *
68 * if mode == 'P' interface only is needed *
69 *****************************************************************************/
70 lofig_list *getlofig (figname, mode)
71 char *figname;
72 char mode;
73 {
74 lofig_list *ptfig;
75 int locked = 0;
76
77 if (HT_LOFIG == NULL) {
78 HT_LOFIG = addht (50);
79 }
80
81 figname = namealloc (figname);
82 /* scan figure list */
83 ptfig = (lofig_list *) gethtitem (HT_LOFIG, figname);
84 if (ptfig == (lofig_list *) EMPTYHT || ptfig == (lofig_list *) DELETEHT)
85 ptfig = NULL;
86 if (ptfig == NULL) {
87 ptfig = HEAD_LOFIG;
88 while (ptfig != NULL && ptfig->NAME != figname)
89 ptfig = ptfig->NEXT;
90 }
91
92 if (ptfig) {
93 if (mode == 'A' && ptfig->MODE == 'P') {
94 locked = islofiglocked (ptfig);
95 if (locked)
96 unlocklofig (ptfig);
97 dellofig (ptfig->NAME);
98 ptfig = NULL;
99 }
100 }
101
102 if (ptfig == NULL) { /* figure doesn't exist */
103 ptfig = (lofig_list *) mbkalloc (sizeof (lofig_list));
104 ptfig->NAME = figname;
105 ptfig->MODELCHAIN = NULL;
106 ptfig->LOINS = NULL;
107 ptfig->LOTRS = NULL;
108 ptfig->LOCON = NULL;
109 ptfig->LOSIG = NULL;
110 mbk_init_NewBKSIG(&ptfig->BKSIG);
111 ptfig->USER = NULL;
112 ptfig->NEXT = HEAD_LOFIG;
113 HEAD_LOFIG = ptfig;
114 ptfig->MODE = mode;
115 addhtitem (HT_LOFIG, figname, (long)ptfig);
116 loadlofig (ptfig, figname, mode);
117 if (locked)
118 locklofig (ptfig);
119 return ptfig;
120 }
121
122 return ptfig;
123 }
124
125 /*******************************************************************************
126 * function givelosig() *
127 *******************************************************************************/
128 losig_list *givelosig (ptfig, index)
129 lofig_list *ptfig;
130 long index;
131 {
132 losig_list *ptsig = NULL;
133 /* ptype_list *pt = NULL;
134 int low;
135 int type;
136 int sigsize;
137 sigsize = getsigsize (ptfig);
138 low = (index % sigsize);
139 type = (index / sigsize);
140 for (pt = ptfig->BKSIG; pt; pt = pt->NEXT)
141 if (pt->TYPE == type)
142 break;
143 if (pt != NULL) {
144 ptsig = (losig_list *) (pt->DATA) + low;
145 if (ptsig->INDEX == index)
146 return ptsig;
147 }*/
148 if (index<=ptfig->BKSIG.maxindex) {
149 ptsig = getlosig(ptfig, index);
150 if (ptsig->INDEX != index) {
151 ptsig->INDEX = index;
152 ptsig->TYPE = 'I';
153 ptsig->NEXT = ptfig->LOSIG;
154 ptfig->LOSIG = ptsig;
155 }
156 }
157 else ptsig = addlosig (ptfig, index, (chain_list *) NULL, 'I');
158 return ptsig;
159 }
160
161 void (*FlattenOnCreateLOTRS) (lotrs_list * tr) = NULL;
162 void (*FlattenOnCreateLOINS) (loins_list * li) = NULL;
163
164 /*******************************************************************************
165 * function flattenlofig() *
166 * *
167 * the instance "insname" is suppressed as a hierarchical level *
168 * in figure pointed by "ptfig". Capacitances and netlist *
169 * consistency is preserved. *
170 * Modified by Gregoire AVOT for rcn support. *
171 *******************************************************************************/
172
173 #define LFCON_TO_INSCON 0xdafe001
174 #define LFSIG_TO_LFEXTCON 0xdafe002
175 #define LF_HIERNAME_TO_NAMEALLOC 0xdafe003
176 #define LFCANDIDAT 0x1
177 #define LFPOSTRAIT 0x2
178 #define LFREBUILDCTC 0x4
179
180
181 void mbk_addvcardnode(losig_list *ls, char *name, float v, long rcn)
182 {
183 ptype_list *pt;
184 chain_list *cl;
185
186 vcardnodeinfo *vni;
187
188 if ((pt=getptype(ls->USER, MBK_VCARD_NODES))==NULL)
189 ls->USER=pt=addptype(ls->USER, MBK_VCARD_NODES, NULL);
190 for (cl=(chain_list *)pt->DATA; cl; cl=cl->NEXT)
191 {
192 vni=(vcardnodeinfo *)cl->DATA;
193 if (vni->value==v && vni->rcn==rcn) break;
194 }
195
196 if (cl==NULL)
197 {
198 vni=(vcardnodeinfo *)mbkalloc(sizeof(vcardnodeinfo));
199 vni->name=name;
200 vni->value=v;
201 vni->rcn=rcn;
202 pt->DATA=addchain((chain_list *)pt->DATA, vni);
203 }
204 }
205
206 void mbk_dupvcardnodes(losig_list *src, losig_list *dest)
207 {
208 ptype_list *pt;
209 chain_list *cl;
210 vcardnodeinfo *vni;
211
212 if ((pt=getptype(src->USER, MBK_VCARD_NODES))!=NULL)
213 {
214 for (cl=(chain_list *)pt->DATA; cl; cl=cl->NEXT)
215 {
216 vni=(vcardnodeinfo *)cl->DATA;
217 mbk_addvcardnode(dest, vni->name, vni->value, vni->rcn);
218 }
219 }
220 }
221
222 static void mbk_flat_locon_pnodename (locon_list * intlocon, loins_list * ptins, char *insname, AdvancedNameAllocator *ana)
223 {
224 locon_list *extlocon;
225 locon_list *testlocon;
226 ptype_list *ptptype, *p0;
227 chain_list *head;
228 chain_list *scan;
229 chain_list *headgoodpnodename;
230 char buf[1024];
231
232 extlocon = NULL;
233 if (MBK_DUP_PNAME_FF == 'Y') {
234 ptptype = getptype (intlocon->SIG->USER, LOFIGCHAIN);
235
236 if (ptptype) {
237
238 head = (chain_list *) ptptype->DATA;
239
240 for (scan = head; scan; scan = scan->NEXT) {
241
242 testlocon = ((locon_list *) (scan->DATA));
243
244 if (testlocon == intlocon)
245 continue;
246
247 if (testlocon->TYPE == EXTERNAL) {
248 extlocon = testlocon;
249 continue;
250 }
251
252 break;
253 }
254 if (scan)
255 extlocon = NULL;
256 }
257
258 if (extlocon) {
259
260 for (testlocon = ptins->LOCON; testlocon; testlocon = testlocon->NEXT)
261 if (testlocon->NAME == extlocon->NAME)
262 break;
263
264 if (testlocon) {
265 extlocon = testlocon;
266 ptptype = getptype (extlocon->USER, PNODENAME);
267 if (ptptype)
268 headgoodpnodename = (chain_list *) ptptype->DATA;
269 else
270 extlocon = NULL;
271 }
272 else
273 extlocon = NULL;
274 }
275 }
276
277 ptptype = getptype (intlocon->USER, PNODENAME);
278 if (extlocon) {
279 if (ptptype) {
280
281 headgoodpnodename=dupchainlst (headgoodpnodename);
282 if ((p0 = getptype (ptins->USER, LF_HIERNAME_TO_NAMEALLOC)) != NULL)
283 {
284 AdvancedNameAllocName (ana, (int)(long)p0->DATA, buf);
285 for (scan = headgoodpnodename; scan; scan = scan->NEXT)
286 scan->DATA = concatname (buf, (char *)(scan->DATA));
287 }
288 else
289 strcpy(buf, ptins->INSNAME);
290
291 freechain(ptptype->DATA);
292 ptptype->DATA=headgoodpnodename;
293 /* intlocon->USER = delptype (intlocon->USER, PNODENAME);
294 intlocon->USER = addptype (intlocon->USER, PNODENAME, headgoodpnodename);*/
295 }
296 }
297 else {
298 if (ptptype) {
299 for (scan = (chain_list *) (ptptype->DATA); scan; scan = scan->NEXT)
300 scan->DATA = concatname (insname, (char *)(scan->DATA));
301 }
302 }
303 }
304
305 void flattenlofig (lofig_list * ptfig, char *insname, char concat)
306 {
307 loins_list *li;
308 AdvancedNameAllocator *ana;
309 chain_list *cl;
310
311 if (MBK_GLOBALPARAMS)
312 {
313 EQT_CONTEXT_HIERARCHY[0]=eqt_init(32);
314 eqt_import_vars (EQT_CONTEXT_HIERARCHY[0], MBK_GLOBALPARAMS);
315 }
316
317 if (insname == NULL)
318 {
319 rflattenlofig(ptfig, concat, NO);
320 }
321 else
322 {
323 ana = CreateAdvancedNameAllocator (CASE_SENSITIVE);
324 li = getloins (ptfig, insname);
325 flattenlofig_bypointer (ptfig, cl = addchain (NULL, li), ana, concat);
326 freechain (cl);
327 flatten_setup_realname_from_hiername (ptfig, ana);
328 FreeAdvancedNameAllocator (ana);
329 }
330
331 if (MBK_GLOBALPARAMS)
332 {
333 eqt_term(EQT_CONTEXT_HIERARCHY[0]);
334 EQT_CONTEXT_HIERARCHY[0] = NULL;
335 }
336 }
337
338 void flattenloinslist(lofig_list * ptfig, chain_list *cl, char concat)
339 {
340 AdvancedNameAllocator *ana;
341 ana = CreateAdvancedNameAllocator (CASE_SENSITIVE);
342 flattenlofig_bypointer (ptfig, cl, ana, concat);
343 flatten_setup_realname_from_hiername (ptfig, ana);
344 FreeAdvancedNameAllocator (ana);
345 }
346
347 static void maken2 (lofig_list * lf, loins_list * li)
348 {
349 locon_list *lcf, *lci;
350 ptype_list *p;
351 for (lcf = lf->LOCON; lcf != NULL; lcf = lcf->NEXT) {
352 if (getptype (lcf->SIG->USER, LFSIG_TO_LFEXTCON) == NULL) {
353 for (lci = li->LOCON; lci != NULL && lci->NAME != lcf->NAME; lci = lci->NEXT);
354 if (lci == NULL) {
355 avt_errmsg(MBK_ERRMSG, "000", AVT_FATAL, lcf->NAME, li->INSNAME);
356 }
357 lcf->USER = addptype (lcf->USER, LFCON_TO_INSCON, lci);
358 if ((p = getptype (lcf->SIG->USER, LFSIG_TO_LFEXTCON)) == NULL)
359 p = lcf->SIG->USER = addptype (lcf->SIG->USER, LFSIG_TO_LFEXTCON, NULL);
360 p->DATA = addchain ((chain_list *) p->DATA, lcf);
361 }
362 }
363 }
364
365 static void addcorresp (lofig_list * lf, loins_list * li)
366 {
367 locon_list *lcf, *lci;
368 ptype_list *p;
369 int swapped = 0;
370 if (lf->LOCON != NULL && li->LOCON != NULL && lf->LOCON->NAME != li->LOCON->NAME) {
371 li->LOCON = (locon_list *) reverse ((chain_list *) li->LOCON);
372 swapped = 1;
373 }
374
375 for (lcf = lf->LOCON, lci = li->LOCON; lcf != NULL && lci != NULL; lcf = lcf->NEXT, lci = lci->NEXT) {
376 if (lcf->NAME != lci->NAME) {
377 maken2 (lf, li);
378 return;
379 }
380 lcf->USER = addptype (lcf->USER, LFCON_TO_INSCON, lci);
381 if ((p = getptype (lcf->SIG->USER, LFSIG_TO_LFEXTCON)) == NULL)
382 p = lcf->SIG->USER = addptype (lcf->SIG->USER, LFSIG_TO_LFEXTCON, NULL);
383 p->DATA = addchain ((chain_list *) p->DATA, lcf);
384 }
385 if (lcf != lci) {
386 avt_errmsg(MBK_ERRMSG, "001", AVT_FATAL, li->INSNAME, lcf->NAME);
387 }
388 if (swapped)
389 li->LOCON = (locon_list *) reverse ((chain_list *) li->LOCON);
390 }
391
392 static chain_list *getsigexternalconnectors (losig_list * ls)
393 {
394 ptype_list *p;
395 chain_list *cl;
396 if ((p = getptype (ls->USER, LFSIG_TO_LFEXTCON)) == NULL)
397 return NULL;
398 cl = (chain_list *) p->DATA;
399 return cl;
400 }
401
402 static locon_list *getcorrespinstanceconnector (locon_list * lc)
403 {
404 ptype_list *p;
405 locon_list *clc;
406 if ((p = getptype (lc->USER, LFCON_TO_INSCON)) == NULL)
407 return NULL;
408 clc = (locon_list *) p->DATA;
409 return clc;
410 }
411
412 static void cleansigexternalconnectors (losig_list * ls)
413 {
414 if (getptype (ls->USER, LFSIG_TO_LFEXTCON) == NULL)
415 exit (4);
416 ls->USER = delptype (ls->USER, LFSIG_TO_LFEXTCON);
417 }
418 static void cleancorrespinstanceconnector (locon_list * lc)
419 {
420 if (getptype (lc->USER, LFCON_TO_INSCON) == NULL)
421 exit (5);
422 lc->USER = delptype (lc->USER, LFCON_TO_INSCON);
423 }
424
425 /* dupliquer le contexte de ptins dans toutes les instances de figins */
426 /* pour chaque instance de figins, evaluer les parametres dans le contexte duplique */
427 /* rajouter les parametres dans le contexte duplique */
428 /* mettre a jour la valeur des resistances, des capas et des transistors dans figins */
429 /* detruire le contexte de ptins */
430
431 //extern eqt_ctx *spi_init_eqt ();
432
433 eqt_param *MBK_GLOBALPARAMS = NULL;
434 chain_list *MBK_GLOBALFUNC=NULL;
435 ht *MBK_MONTE_MODEL_PARAMS=NULL;
436 ptype_list *MBK_MONTE_DIST=NULL;
437 ptype_list *MBK_MONTE_PARAMS=NULL;
438
439 char *mbk_montecarlo_key(char *model, char *subcktname, int type, char location)
440 {
441 char txt[1024];
442 sprintf(txt,"%s::%s::%d::%c", model, subcktname?subcktname:"", type, location);
443 return namealloc(txt);
444 }
445
446 /*extern float SPI_SCALE_CAPAFACTOR;
447 extern float SPI_SCALE_RESIFACTOR;
448 extern float SPI_SCALE_TRANSFACTOR;
449 extern float SPI_SCALE_DIODEFACTOR;
450 */
451 #define EQTFAST 1
452
453 static inline double opt_eval(eqt_ctx *ctx, optparam_list *ptopt)
454 {
455 if (ptopt->EQT_EXPR==NULL)
456 return eqt_eval (ctx, ptopt->UDATA.EXPR, EQTFAST);
457
458 return eqt_calcval (ctx, ptopt->EQT_EXPR);
459 }
460
461 static void print_mlu_error(lofig_list *fig, eqt_ctx *ctx, char *var, char *expr, char *insname, chain_list **unk)
462 {
463 chain_list *cl, *ch;
464 int nb;
465 char buf[2048];
466
467 cl=eqt_GetVariables(ctx, expr, 0);
468 nb=countchain(cl);
469
470 strcpy(buf,"");
471 for (ch=cl; ch!=NULL; ch=ch->NEXT)
472 {
473 if (ch!=cl)
474 {
475 if (ch->NEXT==NULL)
476 strcat(buf,"and ");
477 else
478 strcat(buf,", ");
479 }
480 strcat(buf,"'");
481 strcat(buf,(char *)ch->DATA);
482 strcat(buf,"'");
483 // eqt_addvar(ctx, (char *)ch->DATA, 0);
484 // *unk=addchain(*unk, ch->DATA);
485 }
486 freechain(cl);
487
488 avt_errmsg(MBK_ERRMSG, "052", AVT_ERROR, var, expr, fig->NAME, nb>1?"s":"", buf, nb>1?"are":"is");
489 insname=NULL;
490 }
491
492 int need_scale (char *param)
493 {
494 return (!strcasecmp (param, "sa") || !strcasecmp (param, "sb") || !strcasecmp (param, "sd"));
495 }
496
497 static int m_is_allowed(char what)
498 {
499 switch (what)
500 {
501 case 'i': // instances
502 switch (V_INT_TAB[__SIM_TOOLMODEL].VALUE)
503 {
504 case SIM_TOOLMODEL_ELDO:
505 case SIM_TOOLMODEL_HSPICE:
506 return 1;
507 case SIM_TOOLMODEL_TITAN:
508 case SIM_TOOLMODEL_SPICE:
509 default:
510 return 0;
511 }
512 case 't': // transistors
513 return 1;
514 case 'r': // resistor
515 switch (V_INT_TAB[__SIM_TOOLMODEL].VALUE)
516 {
517 case SIM_TOOLMODEL_ELDO:
518 case SIM_TOOLMODEL_HSPICE:
519 case SIM_TOOLMODEL_TITAN:
520 return 1;
521 case SIM_TOOLMODEL_SPICE:
522 default:
523 return 0;
524 }
525 case 'c': // capacitor
526 switch (V_INT_TAB[__SIM_TOOLMODEL].VALUE)
527 {
528 case SIM_TOOLMODEL_ELDO:
529 case SIM_TOOLMODEL_HSPICE:
530 case SIM_TOOLMODEL_TITAN:
531 return 1;
532 case SIM_TOOLMODEL_SPICE:
533 default:
534 return 0;
535 }
536 }
537 return 0;
538 }
539
540 static eqt_ctx *nom_sub_ctx=NULL;
541
542 static double nom_sub_mod(char *var)
543 {
544 double val=0;
545 val=eqt_getvar_in_context_only(nom_sub_ctx, var);
546 return val;
547 }
548
549 static void flatten_eval_montecarlo(eqt_ctx *evalctx, eqt_ctx *origctx, char *subname, int global)
550 {
551 char *mckey;
552 ptype_list *mcparam, *pt;
553 double *res;
554 int cnt, i;
555 long l;
556 if (MBK_MONTE_MODEL_PARAMS!=NULL)
557 {
558 eqt_setspecialfunc(evalctx, EQTSPECFUNC_NOM_SUB, nom_sub_mod);
559 nom_sub_ctx=origctx;
560 mckey=mbk_montecarlo_key(subname, NULL, 555, global?'G':'L');
561 if ((l=gethtitem(MBK_MONTE_MODEL_PARAMS, mckey))!=EMPTYHT) mcparam=(ptype_list *)l;
562 else mcparam=NULL;
563 cnt=countchain((chain_list *)mcparam);
564 if (cnt>0)
565 {
566 res=(double *)mbkalloc(sizeof(double)*cnt);
567 for (pt=mcparam, i=0; pt!=NULL; pt=pt->NEXT, i++)
568 {
569 res[i]=eqt_eval(evalctx, (char *)pt->DATA, EQTFAST);
570 if (!eqt_resistrue(evalctx))
571 avt_errmsg(MCC_ERRMSG, "038", AVT_ERROR, (char *)pt->TYPE, (char *)pt->DATA, " : set to 0");
572 else if (!finite(res[i]))
573 avt_errmsg(MCC_ERRMSG, "038", AVT_ERROR, (char *)pt->TYPE, (char *)pt->DATA," : returned NaN or Inf");
574 }
575
576 for (pt=mcparam, i=0; pt!=NULL; pt=pt->NEXT, i++)
577 if (eqt_isdefined(origctx, (char *)pt->TYPE, 0))
578 eqt_addvar(origctx, (char *)pt->TYPE, res[i]);
579 else
580 avt_errmsg(MBK_ERRMSG, "053", AVT_ERROR, global?"global":"local", (char *)pt->TYPE, subname);
581
582 mbkfree(res);
583 }
584 nom_sub_ctx=NULL;
585 eqt_setspecialfunc(evalctx, EQTSPECFUNC_NOM_SUB, NULL);
586 }
587 }
588
589 void flatten_parameters (lofig_list * fig, loins_list *ptfatherloins, eqt_param * param_tab, int x, int y,
590 int Tx, int Ty, int R, int A, eqt_ctx **mc_ctx)
591 {
592 optparam_list *optparams, *saveparams, *ptopt, *ptprev, *ptnext;
593 loins_list *ptins, *ptnewloins, *ptnewloinslist=NULL;
594 lotrs_list *pttrs;
595 lotrs_list *ptnewlotrs, *ptnewlotrslist = NULL;
596 ptype_list *ptduptrs, *ptduptrslist = NULL;
597 ptype_list *ptduploins, *ptduploinslist = NULL;
598 ptype_list *ptype;
599 static eqt_ctx *ins_ctx=NULL, *min_ctx=NULL;
600 static eqt_ctx *ctx=NULL;
601 eqt_param *defaults;
602 double value, scale, foundval;
603 double trans_w, trans_l, trans_as, trans_ad;
604 double diode_area, diode_pj, tc1, tc2, dtemp;
605 loctc_list *ptctc;
606 losig_list *ptsig;
607 lofig_list *ptfig;
608 chain_list *ptch;
609 lowire_list *ptwire;
610 locon_list *lc;
611 char *var;
612 lofig_list *ins_fig;
613 ptype_list *xy_ptype;
614 xy_struct *xy;
615 char *diode_model, *diodesubckt;
616 int capa_diode_flag;
617 int model_instance = 0;
618 int i;
619 char namebuf[1024];
620 lofiginfo *lfif;
621 int cntctx=0, newdone, m;
622 int minctx = 0;
623
624 if ((lfif=mbk_getlofiginfo(fig, 0))!=NULL) scale=lfif->scale;
625 else scale=1;
626
627 if (ptfatherloins != NULL)
628 {
629 if ((ptype = getptype(ptfatherloins->USER, MIN_PARAM_CONTEXT)) != NULL)
630 {
631 fig->LOTRS->USER = addptype(fig->LOTRS->USER, PARAM_CONTEXT, ptype->DATA);
632 ptfatherloins->USER = delptype(ptfatherloins->USER, MIN_PARAM_CONTEXT);
633 }
634 }
635
636 if (MLU_TRACE_EQT)
637 fprintf (stdout, "******** FIGURE %s *********\n", fig->NAME);
638
639
640
641 // get default parameters
642
643
644 /* if (*moreparams!=NULL) {
645 for (ptch=*moreparams; ptch!=NULL; ptch=ptch->NEXT) {
646 eqt_addvar(ctx, (char *)ptch->DATA, 0);
647 }
648 }*/
649 if (EQT_CONTEXT_HIERARCHY[0])
650 {
651 minctx++;
652 cntctx++;
653 }
654 else if (MBK_GLOBALPARAMS)
655 {
656 EQT_CONTEXT_HIERARCHY[cntctx]=eqt_init(32);
657 eqt_import_vars (EQT_CONTEXT_HIERARCHY[cntctx], MBK_GLOBALPARAMS);
658 cntctx++;
659 }
660 if (*mc_ctx==NULL && MBK_MONTE_MODEL_PARAMS!=NULL)
661 {
662 *mc_ctx = eqt_init(EQT_NB_VARS) ;
663 eqt_add_spice_extension(*mc_ctx);
664 if (MBK_GLOBALFUNC) eqt_import_func(MBK_GLOBALFUNC, *mc_ctx);
665 mbk_EvalGlobalMonteCarloDistributions(*mc_ctx);
666 }
667
668 if (ctx) eqt_resetvars(ctx, 0);
669 else
670 {
671 ctx = spi_init_eqt ();
672 if (MBK_GLOBALFUNC)
673 eqt_import_func(MBK_GLOBALFUNC, ctx);
674 }
675 if (param_tab)
676 {
677 eqt_ctx *tmpctx;
678 tmpctx=eqt_init(32);
679 eqt_import_vars (tmpctx, param_tab);
680 if (*mc_ctx!=NULL) flatten_eval_montecarlo(*mc_ctx, tmpctx, fig->NAME, 0);
681 EQT_CONTEXT_HIERARCHY[cntctx]=tmpctx;
682 cntctx++;
683 }
684
685 if ((ptype = getptype (fig->USER, OPT_PARAMS)))
686 {
687 static ht *allparams=NULL;
688 if (allparams==NULL) allparams=addht(128);
689 else resetht(allparams);
690 optparams = (optparam_list *) ptype->DATA;
691 for (ptopt = optparams; ptopt; ptopt = ptopt->NEXT)
692 {
693 if (eqt_isdefined(ctx, ptopt->UNAME.SPECIAL, 0)) continue;
694 addhtitem(allparams, ptopt->UNAME.SPECIAL, (long)ptopt->UDATA.EXPR);
695 }
696 mbk_recur_Eval_Start(ctx, allparams, fig->NAME);
697 // delht(allparams);
698 }
699
700 /* if (param_tab)
701 eqt_import_vars (ctx, param_tab);
702 if (MBK_GLOBALFUNC)
703 eqt_import_func(MBK_GLOBALFUNC, ctx);*/
704 defaults = eqt_export_vars (ctx);
705 // ins_ctx=min_ctx=NULL;
706
707 // Update instances
708 for (ptins = fig->LOINS; ptins; ptins = ptins->NEXT) {
709 if (MLU_TRACE_EQT)
710 fprintf (stdout, "\n----------------\nINSTANCE %s\n\n", ptins->INSNAME);
711 if (getptype (ptins->USER, PARAM_CONTEXT))
712 continue;
713
714 ins_fig = getloadedlofig (ptins->FIGNAME);
715 if (ins_fig==NULL) continue;
716
717 if (ins_ctx ==NULL)
718 {
719 if (ins_ctx) eqt_resetvars(ins_ctx, 0);
720 else ins_ctx = spi_init_eqt ();
721 if (MBK_GLOBALFUNC)
722 eqt_import_func(MBK_GLOBALFUNC, ins_ctx);
723 }
724 else eqt_resetvars(ins_ctx, 0);
725
726 /* Test for single transistor instance and save passed parameters for MCC */
727 model_instance = 0;
728 if (ins_fig->LOTRS != NULL && ins_fig->LOTRS->NEXT == NULL) {
729 pttrs = ins_fig->LOTRS;
730 if (getptype(ins_fig->LOTRS->USER, TRANS_FIGURE) != NULL) {
731 model_instance = 1;
732 if (min_ctx==NULL)
733 {
734 min_ctx = spi_init_eqt();
735 if (MBK_GLOBALFUNC)
736 eqt_import_func(MBK_GLOBALFUNC, min_ctx);
737 }
738 else eqt_resetvars(min_ctx, 0);
739 }
740 }
741
742 if (ins_fig && (ptype = getptype (ins_fig->USER, PARAM_CONTEXT))) {
743 eqt_import_vars (ins_ctx, (eqt_param *) ptype->DATA);
744 if (*mc_ctx!=NULL)
745 {
746 eqt_ctx *savectx;
747 if (param_tab)
748 savectx=EQT_CONTEXT_HIERARCHY[cntctx-1], EQT_CONTEXT_HIERARCHY[cntctx-1]=NULL;
749 flatten_eval_montecarlo(*mc_ctx, ins_ctx, ins_fig->NAME, 1);
750 if (param_tab)
751 EQT_CONTEXT_HIERARCHY[cntctx-1]= savectx;
752 }
753 }
754 eqt_import_vars (ins_ctx, defaults);
755
756 if ((ptype = getptype (ptins->USER, OPT_PARAMS))) {
757 int is_m;
758 optparams = (optparam_list *) ptype->DATA;
759
760 for (ptopt = optparams; ptopt; ptopt = ptopt->NEXT) {
761 if (m_is_allowed('i') && !strcasecmp(ptopt->UNAME.SPECIAL, "m")) is_m=1; else is_m=0;
762
763 if (ptopt->TAG == '$') {
764 if (MLU_TRACE_EQT)
765 fprintf (stdout, "PARAM: %s = %s\n", ptopt->UNAME.SPECIAL, ptopt->UDATA.EXPR);
766 value = opt_eval (ins_ctx, ptopt);
767 if (!eqt_resistrue (ins_ctx)) {
768 print_mlu_error(fig, ctx, ptopt->UNAME.SPECIAL, ptopt->UDATA.EXPR, NULL, NULL);
769 value = opt_eval (ctx, ptopt);
770 }
771 else if (!finite(value))
772 avt_errmsg(MBK_ERRMSG, "051", AVT_ERROR, ptopt->UNAME.SPECIAL, ptopt->UDATA.EXPR," : returned NaN or Inf");
773 else if (MLU_TRACE_EQT)
774 fprintf (stdout, "---> '%s' = %g\n", ptopt->UDATA.EXPR, value);
775 if (!is_m) eqt_addvar (ins_ctx, ptopt->UNAME.SPECIAL, value);
776 }
777 else {
778 if (MLU_TRACE_EQT)
779 fprintf (stdout, "PARAM: %s = %g\n", ptopt->UNAME.SPECIAL, ptopt->UDATA.VALUE);
780 if (!is_m) eqt_addvar (ins_ctx, ptopt->UNAME.SPECIAL, ptopt->UDATA.VALUE);
781 value = ptopt->UDATA.VALUE;
782 }
783 if (!is_m && model_instance == 1) eqt_addvar (min_ctx, ptopt->UNAME.SPECIAL, value);
784 if (is_m) {
785 ptduploinslist = addptype(ptduploinslist, mbk_long_round(value), ptins);
786 }
787
788 }
789 freeoptparams (optparams);
790 ptins->USER = delptype (ptins->USER, OPT_PARAMS);
791 /* save min context in instance for MCC */
792 if (model_instance == 1) {
793 ptins->USER = addptype(ptins->USER, MIN_PARAM_CONTEXT, eqt_export_vars(min_ctx));
794 }
795 }
796 ptins->USER = addptype (ptins->USER, PARAM_CONTEXT, eqt_export_vars (ins_ctx));
797
798 if ((xy_ptype = getptype (ptins->USER, MSL_XY_PTYPE))) {
799 xy = (xy_struct*)xy_ptype->DATA;
800 xy->X += x;
801 xy->Y += y;
802 }
803 }
804 // if (ins_ctx!=NULL) eqt_term (ins_ctx);
805 // if (min_ctx!=NULL) eqt_term(min_ctx);
806
807 // update capacitances and wires
808 for (ptsig = fig->LOSIG; ptsig; ptsig = ptsig->NEXT) {
809 if ((var=getlosigalim_expr(ptsig))!=NULL)
810 {
811 value=eqt_eval (ctx, var, EQTFAST);
812 if (!eqt_resistrue (ctx)) {
813 print_mlu_error(fig, ctx, "{voltage source value}", var, NULL, NULL);
814 value = eqt_eval (ctx, var, EQTFAST);
815 }
816 dellosigalim_expr(ptsig);
817 addlosigalim (ptsig, value, NULL);
818 }
819 if (!ptsig->PRCN)
820 continue;
821 for (ptch = ptsig->PRCN->PCTC; ptch; ptch = ptch->NEXT) {
822 ptctc = (loctc_list *) ptch->DATA;
823 if (!(ptype = getptype (ptctc->USER, OPT_PARAMS)))
824 continue;
825 optparams = (optparam_list *) ptype->DATA;
826 capa_diode_flag=0;
827 m=1;
828 foundval=-1;
829 for (ptopt = optparams; ptopt; ptopt = ptopt->NEXT) {
830 var = ptopt->UNAME.SPECIAL;
831 if (!strcasecmp (var, "diode_model")) {
832 diode_model = ptopt->UDATA.EXPR;
833 diodesubckt=NULL;
834 capa_diode_flag = 1;
835 diode_area=1;
836 diode_pj=0;
837 continue; // don't try to evaluate anything
838 }
839 if (!strcasecmp (var, "diode_subckt")) {
840 diodesubckt=ptopt->UDATA.EXPR;
841 continue;
842 }
843 if (ptopt->TAG == '$') {
844 value = opt_eval (ctx, ptopt);
845 if (!eqt_resistrue (ctx)) {
846 print_mlu_error(fig, ctx, "{capa value}", ptopt->UDATA.EXPR, NULL,NULL);
847 value = opt_eval (ctx, ptopt);
848 }
849 else if (!finite(value))
850 avt_errmsg(MBK_ERRMSG, "051", AVT_ERROR, "{capa value}", ptopt->UDATA.EXPR," : returned NaN or Inf");
851 else if (value<0)
852 {
853 avt_errmsg(MBK_ERRMSG, "070", AVT_ERROR, ptopt->UDATA.EXPR, "capacitance");
854 }
855 else if (MLU_TRACE_EQT)
856 fprintf (stdout, "CAPA ---> '%s' = %g\n", ptopt->UDATA.EXPR, value);
857 }
858 else
859 value = ptopt->UDATA.VALUE;
860
861 if (m_is_allowed('c') && !strcasecmp (var, "m"))
862 {
863 m=mbk_long_round(value);
864 }
865 else if (!strcasecmp (var, "val")) {
866 foundval=value;
867 }
868 else if (!strcasecmp (var, "diode_area")) {
869 value*=scale*scale;
870 capa_diode_flag = 1;
871 diode_area = value;
872 }
873 else if (!strcasecmp (var, "diode_pj")) {
874 value*=scale;
875 capa_diode_flag = 1;
876 diode_pj = value;
877 }
878 }
879 if (foundval!=-1)
880 {
881 rcn_removecapa(ptctc->SIG1, ptctc->CAPA);
882 rcn_removecapa(ptctc->SIG2, ptctc->CAPA);
883 ptctc->CAPA = foundval * SPI_SCALE_CAPAFACTOR * 1e12* m;
884 rcn_addcapa(ptctc->SIG1, ptctc->CAPA);
885 rcn_addcapa(ptctc->SIG2, ptctc->CAPA);
886 }
887 else
888 ptctc->CAPA*=m;
889 if ( capa_diode_flag ) {
890 /* if ( (ptfig = getloadedlofig(fig->NAME) )) {
891 if ( (ptype = getptype(ptfig->USER,PARAM_CONTEXT) ) ) {
892 eqt_free_param (ptype->DATA);
893 ptype->DATA = eqt_export_vars (ctx);
894 }
895
896 }*/
897 MCC_CURRENT_SUBCKT=diodesubckt;
898 value = mcc_calcDioCapa ( MCC_MODELFILE, diode_model,
899 MCC_DIODE, MCC_TYPICAL,
900 0.0, MCC_VDDmax, MCC_TEMP,
901 (diode_area > 0.0) ? diode_area:0.0,
902 (diode_pj > 0.0) ? diode_pj:0.0
903 );
904 if (!finite(value))
905 avt_errmsg(MBK_ERRMSG, "071", AVT_ERROR, "NaN or Inf for");
906 else if (value<0)
907 avt_errmsg(MBK_ERRMSG, "071", AVT_ERROR, "negative");
908 MCC_CURRENT_SUBCKT=NULL;
909 rcn_removecapa(ptctc->SIG1, ptctc->CAPA);
910 rcn_removecapa(ptctc->SIG2, ptctc->CAPA);
911 ptctc->CAPA = value * SPI_SCALE_CAPAFACTOR * 1.0e12;
912 rcn_addcapa(ptctc->SIG1, ptctc->CAPA);
913 rcn_addcapa(ptctc->SIG2, ptctc->CAPA);
914 if ( !rcn_isCapaDiode (ptctc) )
915 rcn_setCapaDiode( ptctc, 1);
916 }
917
918 freeoptparams (optparams);
919 ptctc->USER = delptype (ptctc->USER, OPT_PARAMS);
920 }
921 for (ptwire = ptsig->PRCN->PWIRE; ptwire; ptwire = ptwire->NEXT) {
922 if (!(ptype = getptype (ptwire->USER, OPT_PARAMS)))
923 continue;
924 optparams = (optparam_list *) ptype->DATA;
925 m=1;
926 foundval=-1;
927 tc1=0; tc2=0; dtemp=0;
928 for (ptopt = optparams; ptopt; ptopt = ptopt->NEXT) {
929 var = ptopt->UNAME.SPECIAL;
930 if (ptopt->TAG == '$') {
931 value = opt_eval (ctx, ptopt);
932 if (!eqt_resistrue (ctx)) {
933 print_mlu_error(fig, ctx, var, ptopt->UDATA.EXPR, NULL, NULL);
934 value = opt_eval (ctx, ptopt);
935 }
936 else if (!finite(value))
937 avt_errmsg(MBK_ERRMSG, "051", AVT_ERROR, var, ptopt->UDATA.EXPR," : returned NaN or Inf");
938 else if (MLU_TRACE_EQT)
939 fprintf (stdout, "RESI ---> '%s' = %g\n", ptopt->UDATA.EXPR, value);
940 }
941 else
942 value = ptopt->UDATA.VALUE;
943
944 if (m_is_allowed('r') && !strcasecmp (var, "m"))
945 m=mbk_long_round(value);
946 else if (!strcasecmp (var, "val") || !strcasecmp (var,"r"))
947 {
948 foundval=value;
949 if (value<0)
950 {
951 avt_errmsg(MBK_ERRMSG, "070", AVT_ERROR, ptopt->UDATA.EXPR, "resistance");
952 }
953 }
954 else if (!strcasecmp (var, "tc1")) tc1=value;
955 else if (!strcasecmp (var, "tc2")) tc2=value;
956 else if (!strcasecmp (var, "dtemp")) dtemp=value;
957 }
958
959 if (foundval==-1) foundval=ptwire->RESI/SPI_SCALE_RESIFACTOR;
960
961 ptwire->RESI = mcc_calcResiSimple(foundval, tc1, tc2, dtemp)* SPI_SCALE_RESIFACTOR/(double)m ;
962 /*
963 if (foundval==-1)
964 ptwire->RESI/=m;
965 else
966 ptwire->RESI =(foundval * SPI_SCALE_RESIFACTOR)/(double)m;
967 */
968 freeoptparams (optparams);
969 ptwire->USER = delptype (ptwire->USER, OPT_PARAMS);
970 }
971 }
972
973 // update transistor sizes
974 for (pttrs = fig->LOTRS; pttrs; pttrs = pttrs->NEXT) {
975 if (pttrs->X!=LONG_MIN) pttrs->X += x;
976 if (pttrs->Y!=LONG_MIN) pttrs->Y += y;
977 if (!(ptype = getptype (pttrs->USER, OPT_PARAMS)))
978 continue;
979 trans_l = 0.0;
980 trans_w = 0.0;
981 trans_as = 0.0;
982 trans_ad = 0.0;
983 diode_area = 0.0;
984 diode_pj = 0.0;
985
986 optparams = (optparam_list *) ptype->DATA;
987 ptprev = NULL;
988 saveparams = NULL;
989 for (ptopt = optparams; ptopt; ptopt = ptnext) {
990 ptnext = ptopt->NEXT;
991 if (isknowntrsparam (ptopt->UNAME.STANDARD)) {
992 if (**(ptopt->UNAME.STANDARD) == '$') {
993 value = opt_eval (ctx, ptopt);
994 if (!eqt_resistrue (ctx)) {
995 value = 0.0;
996 print_mlu_error(fig, ctx, *(ptopt->UNAME.STANDARD-1), ptopt->UDATA.EXPR, NULL, NULL);
997 // avt_errmsg(MBK_ERRMSG, "002", AVT_ERROR, ptopt->UDATA.EXPR);
998 }
999 else if (!finite(value))
1000 avt_errmsg(MBK_ERRMSG, "051", AVT_ERROR, *(ptopt->UNAME.STANDARD-1), ptopt->UDATA.EXPR," : returned NaN or Inf");
1001 ptopt->UNAME.STANDARD -= 1;
1002 if (need_scale (*(ptopt->UNAME.STANDARD))) ptopt->UDATA.VALUE = value * scale;
1003 else ptopt->UDATA.VALUE = value;
1004
1005 }
1006 if (m_is_allowed('t') && ptopt->UNAME.STANDARD == MBK_M) {
1007 ptduptrslist = addptype(ptduptrslist, value, pttrs);
1008 ptprev = ptopt;
1009 continue;
1010 }
1011 ptopt->NEXT = saveparams;
1012 saveparams = ptopt;
1013 if (ptprev == NULL)
1014 ptype->DATA = ptnext;
1015 else
1016 ptprev->NEXT = ptnext;
1017 continue;
1018 }
1019 if (ptopt->TAG == '$') {
1020 var = ptopt->UNAME.SPECIAL;
1021 value = opt_eval (ctx, ptopt);
1022 if (!eqt_resistrue (ctx)) {
1023 value = 0.0;
1024 print_mlu_error(fig, ctx, var, ptopt->UDATA.EXPR, NULL, NULL);
1025 // avt_errmsg(MBK_ERRMSG, "002", AVT_ERROR, ptopt->UDATA.EXPR);
1026 }
1027 else if (!finite(value))
1028 avt_errmsg(MBK_ERRMSG, "051", AVT_ERROR, var, ptopt->UDATA.EXPR," : returned NaN or Inf");
1029 }
1030 else {
1031 var = ptopt->UNAME.SPECIAL;
1032 value = ptopt->UDATA.VALUE;
1033 }
1034
1035 if (!strcasecmp (var, "l")) {
1036 value*=scale;
1037 trans_l = value;
1038 pttrs->LENGTH = (long)(value * SCALE_X * 1E6 * SPI_SCALE_TRANSFACTOR + 0.5);
1039 if (MLU_TRACE_EQT)
1040 fprintf (stdout, "TRANS ---> %s: '%s' = %g\n", var, ptopt->UDATA.EXPR, value);
1041 }
1042 else if (!strcasecmp (var, "w")) {
1043 value*=scale;
1044 trans_w = value;
1045 pttrs->WIDTH = (long)(value * SCALE_X * 1E6 * SPI_SCALE_TRANSFACTOR + 0.5);
1046 if (MLU_TRACE_EQT)
1047 fprintf (stdout, "TRANS ---> %s: '%s' = %g\n", var, ptopt->UDATA.EXPR, value);
1048 }
1049 else if (!strcasecmp (var, "as")) {
1050 value*=scale*scale;
1051 trans_as = value;
1052 if (MLU_TRACE_EQT)
1053 fprintf (stdout, "TRANS ---> %s: '%s' = %g\n", var, ptopt->UDATA.EXPR, value);
1054 }
1055 else if (!strcasecmp (var, "ad")) {
1056 value*=scale*scale;
1057 trans_ad = value;
1058 if (MLU_TRACE_EQT)
1059 fprintf (stdout, "TRANS ---> %s: '%s' = %g\n", var, ptopt->UDATA.EXPR, value);
1060 }
1061 else if (!strcasecmp (var, "ps")) {
1062 value*=scale;
1063 pttrs->PS = (long)(value * SCALE_X * 1E6 * SPI_SCALE_TRANSFACTOR + 0.5);
1064 if (MLU_TRACE_EQT)
1065 fprintf (stdout, "TRANS ---> %s: '%s' = %g\n", var, ptopt->UDATA.EXPR, value);
1066 }
1067 else if (!strcasecmp (var, "pd")) {
1068 value*=scale;
1069 pttrs->PD = (long)(value * SCALE_X * 1E6 * SPI_SCALE_TRANSFACTOR + 0.5);
1070 if (MLU_TRACE_EQT)
1071 fprintf (stdout, "TRANS ---> %s: '%s' = %g\n", var, ptopt->UDATA.EXPR, value);
1072 }
1073 else if (!strcasecmp (var, "diode_area")) {
1074 value*=scale*scale;
1075 diode_area = value;
1076 if (MLU_TRACE_EQT)
1077 fprintf (stdout, "TRANS ---> %s: '%s' = %g\n", var, ptopt->UDATA.EXPR, value);
1078 }
1079 else if (!strcasecmp (var, "diode_pj")) {
1080 value*=scale;
1081 diode_pj = value;
1082 if (MLU_TRACE_EQT)
1083 fprintf (stdout, "TRANS ---> %s: '%s' = %g\n", var, ptopt->UDATA.EXPR, value);
1084 }
1085 else {
1086 if (ptopt->TAG == '$') {
1087 ptopt->UNAME.SPECIAL = namealloc (var);
1088 ptopt->UDATA.VALUE = value;
1089 ptopt->TAG = ' ';
1090 }
1091 ptopt->NEXT = saveparams;
1092 saveparams = ptopt;
1093 if (ptprev == NULL)
1094 ptype->DATA = ptnext;
1095 else
1096 ptprev->NEXT = ptnext;
1097 continue;
1098 }
1099 ptprev = ptopt;
1100 }
1101 if (trans_w != 0 && trans_as != 0) {
1102 pttrs->XS =
1103 (long)(((pttrs->WIDTH != 0) ? (trans_as * SCALE_X * 1E6 * SPI_SCALE_TRANSFACTOR / trans_w) : 0) + 0.5);
1104 }
1105 if (trans_w != 0 && trans_ad != 0) {
1106 pttrs->XD =
1107 (long)(((pttrs->WIDTH != 0) ? (trans_ad * SCALE_X * 1E6 * SPI_SCALE_TRANSFACTOR / trans_w) : 0) + 0.5);
1108 }
1109
1110 if (diode_area != 0 && diode_pj != 0) {
1111 pttrs->PD = (long)(diode_pj * SCALE_X * 1E6 * SPI_SCALE_DIODEFACTOR + 0.5);
1112 pttrs->XD = (long)(((diode_area * SPI_SCALE_DIODEFACTOR * SCALE_X * 1E6) / (diode_pj / 4)) + 0.5);
1113 }
1114
1115 freeoptparams ((optparam_list *) ptype->DATA);
1116 pttrs->USER = delptype (pttrs->USER, OPT_PARAMS);
1117 if (saveparams)
1118 pttrs->USER = addptype (pttrs->USER, OPT_PARAMS, saveparams);
1119 if (!pttrs->LENGTH && MLU_TRACE_EQT)
1120 avt_errmsg(MBK_ERRMSG, "003", AVT_WARNING);
1121 if (!pttrs->WIDTH && MLU_TRACE_EQT)
1122 avt_errmsg(MBK_ERRMSG, "004", AVT_WARNING);
1123 }
1124
1125 // create new transistors due to M factor and update lofigchain
1126 for (ptduptrs = ptduptrslist; ptduptrs; ptduptrs = ptduptrs->NEXT) {
1127 for (i=1; i < ptduptrs->TYPE; i++) {
1128 ptnewlotrs = rduplotrs((lotrs_list *)ptduptrs->DATA);
1129 if (ptnewlotrs->TRNAME) {
1130 sprintf(namebuf, "%s_m%d", ptnewlotrs->TRNAME, i);
1131 ptnewlotrs->TRNAME = namealloc(namebuf);
1132 }
1133 ptnewlotrs->NEXT = ptnewlotrslist;
1134 ptnewlotrslist = ptnewlotrs;
1135 ptype = getptype(ptnewlotrs->GRID->SIG->USER, LOFIGCHAIN);
1136 if (ptype) {
1137 ptype->DATA = addchain((chain_list *)ptype->DATA, ptnewlotrs->GRID);
1138 }
1139 ptype = getptype(ptnewlotrs->DRAIN->SIG->USER, LOFIGCHAIN);
1140 if (ptype) {
1141 ptype->DATA = addchain((chain_list *)ptype->DATA, ptnewlotrs->DRAIN);
1142 }
1143 ptype = getptype(ptnewlotrs->SOURCE->SIG->USER, LOFIGCHAIN);
1144 if (ptype) {
1145 ptype->DATA = addchain((chain_list *)ptype->DATA, ptnewlotrs->SOURCE);
1146 }
1147 if (ptnewlotrs->BULK) {
1148 ptype = getptype(ptnewlotrs->BULK->SIG->USER, LOFIGCHAIN);
1149 if (ptype) {
1150 ptype->DATA = addchain((chain_list *)ptype->DATA, ptnewlotrs->BULK);
1151 }
1152 }
1153 }
1154 }
1155 freeptype(ptduptrslist);
1156
1157 // add new transistors due to M factor
1158 fig->LOTRS = (lotrs_list *)append((chain_list *)ptnewlotrslist, (chain_list *)fig->LOTRS);
1159
1160 // create new instances due to M factor and update lofigchain
1161 for (ptduptrs = ptduploinslist; ptduptrs; ptduptrs = ptduptrs->NEXT) {
1162 for (i=1; i < ptduptrs->TYPE; i++) {
1163 ptins=(loins_list *)ptduptrs->DATA;
1164 ptnewloins = rduploins(ptins);
1165 sprintf(namebuf, "%s_m%d", ptnewloins->INSNAME, i);
1166 ptnewloins->INSNAME = namealloc(namebuf);
1167 ptnewloins->NEXT = ptnewloinslist;
1168 ptnewloinslist = ptnewloins;
1169
1170 if ((ptype = getptype (ptins->USER, PARAM_CONTEXT))!=NULL)
1171 {
1172 ptnewloins->USER=addptype(ptnewloins->USER, PARAM_CONTEXT, eqt_dupvars((eqt_param *)ptype->DATA));
1173 }
1174 for (lc=ptnewloins->LOCON; lc!=NULL; lc=lc->NEXT)
1175 {
1176 ptype = getptype(lc->SIG->USER, LOFIGCHAIN);
1177 if (ptype) {
1178 ptype->DATA = addchain((chain_list *)ptype->DATA, lc);
1179 }
1180 }
1181 }
1182 }
1183 freeptype(ptduploinslist);
1184
1185 // add new transistors due to M factor
1186 fig->LOINS = (loins_list *)append((chain_list *)ptnewloinslist, (chain_list *)fig->LOINS);
1187
1188 // eqt_term (ctx);
1189 if (defaults)
1190 eqt_free_param (defaults);
1191
1192 for (i=minctx; i<cntctx; i++)
1193 {
1194 eqt_term(EQT_CONTEXT_HIERARCHY[i]);
1195 EQT_CONTEXT_HIERARCHY[i]=NULL;
1196 }
1197 Tx=Ty=R=A=0; // avoid warning
1198 }
1199
1200
1201 void mbk_transfert_loins_params (loins_list * li, lofig_list * origlf, lofig_list * newlf)
1202 {
1203 eqt_ctx *ctx;
1204 ptype_list *ptype;
1205 eqt_param *temp;
1206
1207 ctx = spi_init_eqt ();
1208 if ((ptype = getptype (origlf->USER, PARAM_CONTEXT))) {
1209 eqt_import_vars (ctx, (eqt_param *) ptype->DATA);
1210 }
1211 if ((ptype = getptype (li->USER, PARAM_CONTEXT))) {
1212 eqt_import_vars (ctx, (eqt_param *) ptype->DATA);
1213 }
1214
1215 newlf->USER = addptype (newlf->USER, PARAM_CONTEXT, eqt_export_vars (ctx));
1216 eqt_term (ctx);
1217 }
1218
1219
1220 static void cleanlofigchain_from_to_be_freed_connectors (losig_list * ls)
1221 {
1222 ptype_list *p;
1223 chain_list *cl, *prev, *next;
1224 if ((ls->FLAGS & LFCANDIDAT) == 0)
1225 return;
1226 ls->FLAGS &= ~LFCANDIDAT;
1227 if ((p = getptype (ls->USER, LOFIGCHAIN)) == NULL)
1228 return;
1229
1230 prev = NULL;
1231 for (cl = (chain_list *) p->DATA; cl != NULL; cl = next) {
1232 next = cl->NEXT;
1233 if (((locon_list *) cl->DATA)->DIRECTION == -1) {
1234 if (prev == NULL)
1235 p->DATA = delchain ((chain_list *) p->DATA, (chain_list *) p->DATA);
1236 else
1237 prev->NEXT = delchain (prev->NEXT, cl);
1238 }
1239 else
1240 prev = cl;
1241 }
1242 }
1243
1244 #ifdef BASE_STAT
1245 extern long ynmsize, i_nbptype, i_nbchain, i_nbnum;
1246 #endif
1247
1248 void flatten_setup_realname_from_hiername (lofig_list * lf, AdvancedNameAllocator * ana)
1249 {
1250 loins_list *li;
1251 ptype_list *p0;
1252 locon_list *scanlocon;
1253 chain_list *scanchain;
1254 char *c, buf[2048];
1255
1256 for (li = lf->LOINS; li != NULL; li = li->NEXT) {
1257 if ((p0 = getptype (li->USER, LF_HIERNAME_TO_NAMEALLOC)) != NULL) {
1258 AdvancedNameAllocName (ana, (int)(long)p0->DATA, buf);
1259 li->INSNAME = namealloc (buf);
1260 li->USER = delptype (li->USER, LF_HIERNAME_TO_NAMEALLOC);
1261
1262 c = strrchr (buf, SEPAR);
1263 if (c == NULL)
1264 EXIT (77);
1265 *c = '\0';
1266 for (scanlocon = li->LOCON; scanlocon; scanlocon = scanlocon->NEXT) {
1267 if ((p0 = getptype (scanlocon->USER, PNODENAME)) != NULL) {
1268 for (scanchain = (chain_list *) p0->DATA; scanchain; scanchain = scanchain->NEXT)
1269 scanchain->DATA = concatname (buf, (char *)scanchain->DATA);
1270 }
1271 }
1272 }
1273 }
1274 }
1275 // -------------------
1276 static int buildmatchrule(inffig_list *ifl, char *section, mbk_match_rules *mr)
1277 {
1278 chain_list *cl;
1279 mbk_CreateREGEX(mr, CASE_SENSITIVE, 0);
1280 if (ifl==NULL) return 0;
1281 if (inf_GetPointer(ifl, section, "", (void **)&cl))
1282 {
1283 while (cl!=NULL)
1284 {
1285 mbk_AddREGEX(mr, ((inf_assoc *)cl->DATA)->orig);
1286 cl=cl->NEXT;
1287 }
1288 return 1;
1289 }
1290 return 0;
1291 }
1292 // -------------------
1293 static inline int sighasnorc(losig_list *ls)
1294 {
1295 if (ls->PRCN==NULL || mbk_LosigIsVSS(ls) || mbk_LosigIsVDD(ls) || ls->PRCN->PWIRE==NULL) return 1;
1296 return 0;
1297 }
1298
1299
1300 static void lazy_duplosigalim(losig_list *scanlosig, losig_list *newsig)
1301 {
1302 float val, val1;
1303 if (getlosigalim(newsig, &val) && getlosigalim(scanlosig, &val1))
1304 {
1305 if (fabs(val-val1)>1e-3)
1306 avt_errmsg(MBK_ERRMSG, "005", AVT_WARNING, getsigname(newsig), val, val1);
1307 }
1308 else
1309 {
1310 duplosigalim (scanlosig, newsig);
1311 newsig->ALIMFLAGS|=scanlosig->ALIMFLAGS;
1312 }
1313 }
1314
1315 static void transfert_direction_information_from_instance_to_figure(loins_list *li, lofig_list *lf)
1316 {
1317 locon_list *lc, *lflc;
1318 ptype_list *pt;
1319 for (lc=li->LOCON, lflc=lf->LOCON; lc!=NULL && lflc!=NULL; lc=lc->NEXT, lflc=lflc->NEXT)
1320 {
1321 if (lflc->DIRECTION==UNKNOWN && (pt=getptype(lc->USER, LOCON_INFORMATION))!=NULL)
1322 {
1323 if ((long)pt->DATA==LOCON_INFORMATION_INPUT) lflc->DIRECTION=IN;
1324 else if ((long)pt->DATA==LOCON_INFORMATION_OUTPUT) lflc->DIRECTION=OUT;
1325 }
1326 }
1327 }
1328
1329 // -------------------
1330 void flattenlofig_bypointer (lofig_list * ptfig, chain_list * ptinslist, AdvancedNameAllocator * ana, char concat)
1331 {
1332 struct st_interf {
1333 struct st_interf *next;
1334 int base;
1335 losig_list *sig;
1336 };
1337
1338 struct st_contact {
1339 struct st_contact *next;
1340 locon_list *con1; /* on instance */
1341 int node1;
1342 locon_list *con2; /* on lofig of instance */
1343 int node2;
1344 int interf;
1345 };
1346
1347 chain_list *nextscanctc;
1348 loins_list *ptins;
1349 lofig_list *figins;
1350 losig_list *scanlosig;
1351 int maxsig;
1352 locon_list *ptcon;
1353 chain_list *scanchain, *cl;
1354 ptype_list *ptptype;
1355 struct st_interf *interf;
1356 struct st_interf *ptinterf;
1357 struct st_contact *contact;
1358 struct st_contact *ptcontact;
1359 int nbinterf;
1360 num_list *sn1;
1361 num_list *sn2;
1362 lowire_list *scanwire, *curwire;
1363 int node1;
1364 struct st_interf *ctinterf;
1365 int *newnode;
1366 losig_list *newsig;
1367 locon_list *scanlocon;
1368 int maxnode;
1369 chain_list *scanctc;
1370 locon_list *nextlocon;
1371 void *forfree;
1372 loctc_list *ptctc;
1373 loctc_list *ptctc2;
1374 chain_list *prevctc;
1375 int othernode;
1376 int scanctcnode;
1377 losig_list *othersig;
1378 chain_list *posttreatsig = NULL;
1379 // ptype_list *ptbksig = NULL;
1380 int maxnode_itrf;
1381 int newnode_itrf;
1382 chain_list *chainhtab;
1383 chain_list *chainht;
1384 char buf_insname[2048];
1385 char *insname = buf_insname;
1386 int insname_length;
1387 int verif;
1388 locon_list *eptcon;
1389
1390 lotrs_list *scantrs;
1391 loins_list *scanins;
1392
1393 int i, cnt;
1394 char all;
1395 long key;
1396 ht *htab;
1397
1398 chain_list *rebuildctc = NULL, *candidat_list = NULL;
1399 char iscache, *name;
1400 HeapAlloc contact_heap, interf_heap;
1401 eqt_param *param;
1402 ptype_list *ptype, *p0;
1403 int IDLE_LOCON = 0, GROUP_MODE = 1;
1404 struct st_interf *best;
1405 ptype_list *xy_ptype;
1406 xy_struct *xy;
1407 int x, y, Tx, Ty, R, A;
1408 eqt_ctx *mc_ctx=NULL;
1409
1410
1411 long nbtr = 0, nbins = 0, nblocon = 0;
1412 long newlosig = 0, nblorc = 0;
1413 long cntpost = 0, cntrebui = 0;
1414 void *nextkey ;
1415 long nextitem ;
1416
1417 mbk_match_rules IGNORE_TRANSISTOR;
1418 mbk_match_rules IGNORE_INSTANCE;
1419 mbk_match_rules IGNORE_RESISTANCE;
1420 mbk_match_rules IGNORE_CAPACITANCE, IGNORE_DIODE, *ic_or_id;
1421 mbk_match_rules IGNORE_NAMES;
1422
1423 inffig_list *ifl;
1424 //---------NEW-------------
1425 ht *globalht=NULL;
1426 int local_concat, keptoldsig, has_ignore_names;
1427 // ------ end of declarations ------------
1428
1429 MBK_HANDLE_GLOBAL_NODES=V_BOOL_TAB[__MBK_HANDLE_GLOBAL_NODES].VALUE;
1430
1431 ifl=getloadedinffig(ptfig->NAME);
1432 buildmatchrule(ifl, INF_IGNORE_TRANSISTOR, &IGNORE_TRANSISTOR);
1433 buildmatchrule(ifl, INF_IGNORE_INSTANCE, &IGNORE_INSTANCE);
1434 buildmatchrule(ifl, INF_IGNORE_RESISTANCE, &IGNORE_RESISTANCE);
1435 buildmatchrule(ifl, INF_IGNORE_CAPACITANCE, &IGNORE_CAPACITANCE);
1436 buildmatchrule(ifl, INF_IGNORE_DIODE, &IGNORE_DIODE);
1437 has_ignore_names=buildmatchrule(ifl, INF_IGNORE_NAMES, &IGNORE_NAMES);
1438
1439 CreateHeap (sizeof (struct st_contact), 1024, &contact_heap);
1440 CreateHeap (sizeof (struct st_interf), 1024, &interf_heap);
1441
1442 if( rcn_getlofigcache( ptfig ) ) {
1443 avt_errmsg(MBK_ERRMSG, "006", AVT_FATAL, ptfig->NAME);
1444 return;
1445 }
1446
1447 if ((ptype = getptype (ptfig->USER, PARAM_CONTEXT))) {
1448 flatten_parameters (ptfig, NULL, param = (eqt_param *) ptype->DATA, 0, 0, 0, 0, 0, 0, &mc_ctx);
1449 }
1450 else
1451 flatten_parameters (ptfig, NULL, NULL, 0, 0, 0, 0, 0, 0, &mc_ctx);
1452
1453 /* recupere l'index maximum des signaux sur la figure */
1454 /* maxsig = -1;
1455 for (ptptype = ptfig->BKSIG; ptptype; ptptype = ptptype->NEXT) {
1456 if (ptptype->TYPE > maxsig) {
1457 maxsig = ptptype->TYPE;
1458 ptbksig = ptptype;
1459 }
1460 }
1461
1462 scanlosig = (losig_list *) (ptbksig->DATA);
1463 for (i = 0; i < getsigsize (ptfig); i++) {
1464 if (scanlosig[i].INDEX > maxsig)
1465 maxsig = scanlosig[i].INDEX;
1466 }
1467 */
1468 if (ptfig->BKSIG.TAB==NULL) maxsig=0;
1469 else maxsig=ptfig->BKSIG.maxindex;
1470 maxsig++;
1471
1472
1473 for (scanlosig = ptfig->LOSIG; scanlosig != NULL; scanlosig = scanlosig->NEXT)
1474 scanlosig->FLAGS = 0; // pas candidat
1475
1476 /* si insname == NULL on met a plat au niveau transistor */
1477
1478 if (ptinslist == NULL) {
1479 all = 'Y';
1480 }
1481 else {
1482 all = 'N';
1483 if (ptinslist->NEXT == NULL)
1484 GROUP_MODE = 0;
1485 }
1486
1487 /* On verifie que le lofigchain est bien a jour. Tous les signaux d'une
1488 * lofig ont le ptype dans leur champ USER, meme si il est vide */
1489
1490 if (!getptype (ptfig->LOSIG->USER, LOFIGCHAIN)) {
1491 avt_errmsg(MBK_ERRMSG, "007", AVT_WARNING, ptfig->NAME);
1492
1493 lofigchain (ptfig);
1494 }
1495
1496 if (rcn_getlofigcache (ptfig))
1497 iscache = 1;
1498 else
1499 iscache = 0;
1500
1501 while (ptfig->LOINS != NULL) {
1502 if (all == 'Y') {
1503 ptins = ptfig->LOINS;
1504 }
1505 else {
1506 ptins = (loins_list *) ptinslist->DATA;
1507 ptinslist = ptinslist->NEXT;
1508 }
1509
1510 if ((p0 = getptype (ptins->USER, LF_HIERNAME_TO_NAMEALLOC)) == NULL)
1511 strcpy (buf_insname, ptins->INSNAME);
1512 else
1513 AdvancedNameAllocName (ana, (int)(long)p0->DATA, buf_insname);
1514
1515 insname_length = strlen (insname);
1516
1517 figins = rduplofig (getlofig (ptins->FIGNAME, 'A'));
1518
1519 lofigchain (figins);
1520
1521 transfert_direction_information_from_instance_to_figure(ptins, figins);
1522 mbk_set_transistor_instance_connector_orientation_info (figins);
1523
1524 if ((xy_ptype = getptype (ptins->USER, MSL_XY_PTYPE))) {
1525 xy = (xy_struct*)xy_ptype->DATA;
1526 x = xy->X;
1527 y = xy->Y;
1528 Tx = xy->Tx;
1529 Ty = xy->Ty;
1530 R = xy->R;
1531 A = xy->A;
1532 }
1533 else {
1534 x = 0;
1535 y = 0;
1536 Tx = 0;
1537 Ty = 0;
1538 R = 0;
1539 A = 0;
1540 }
1541
1542 if ((ptype = getptype (ptins->USER, PARAM_CONTEXT))) {
1543 flatten_parameters (figins, ptins, param = (eqt_param *) ptype->DATA, x, y, Tx, Ty, R, A, &mc_ctx);
1544 ptins->USER = delptype (ptins->USER, PARAM_CONTEXT);
1545 if (param)
1546 eqt_free_param (param);
1547 if ((xy_ptype = getptype (ptins->USER, MSL_XY_PTYPE))) {
1548 mbkfree (xy_ptype->DATA);
1549 ptins->USER = delptype (ptins->USER, MSL_XY_PTYPE);
1550 }
1551 }
1552 else {
1553 fprintf (stderr, "NO CONTEXT FOR '%s'\n", ptins->INSNAME);
1554 }
1555
1556 if ((ptptype=getptype(ptins->USER, BBOX_AS_UNUSED))!=NULL) name=(char *)ptptype->DATA;
1557 else name=NULL;
1558
1559 if (concat != NO) {
1560 int insnameindex, removed=0;
1561 for (scanins = figins->LOINS; scanins; scanins = scanins->NEXT) {
1562 strcpy (&buf_insname[insname_length + 1], scanins->INSNAME);
1563 buf_insname[insname_length] = SEPAR;
1564
1565 if (name!=NULL) scanins->USER=addptype(scanins->USER, BBOX_AS_UNUSED, name);
1566
1567 if (mbk_CheckREGEX(&IGNORE_INSTANCE, buf_insname)==0)
1568 {
1569 insnameindex = AdvancedNameAlloc (ana, buf_insname);
1570
1571 scanins->USER = addptype (scanins->USER, LF_HIERNAME_TO_NAMEALLOC, (void *)(long)insnameindex);
1572 }
1573 else
1574 {
1575 avt_log( LOGSTATPRS, 3, "instance '%s' ignored in circuit '%s'\n", buf_insname, ptfig->NAME);
1576 scanins->INSNAME=NULL, removed++; // marquage pour remove
1577 }
1578 buf_insname[insname_length] = '\0';
1579 }
1580
1581 for (scantrs = figins->LOTRS; scantrs; scantrs = scantrs->NEXT) {
1582 if (scantrs->TRNAME)
1583 scantrs->TRNAME = concatname (insname, scantrs->TRNAME);
1584
1585 if (name!=NULL) scantrs->USER=addptype(scantrs->USER, BBOX_AS_UNUSED, name);
1586
1587 if (mbk_CheckREGEX(&IGNORE_TRANSISTOR, scantrs->TRNAME)==0)
1588 {
1589 mbk_flat_locon_pnodename (scantrs->DRAIN, ptins, insname, ana);
1590 mbk_flat_locon_pnodename (scantrs->GRID, ptins, insname, ana);
1591 mbk_flat_locon_pnodename (scantrs->SOURCE, ptins, insname, ana);
1592
1593 if (scantrs->BULK)
1594 if (scantrs->BULK->SIG)
1595 mbk_flat_locon_pnodename (scantrs->BULK, ptins, insname, ana);
1596 }
1597 else
1598 {
1599 avt_log( LOGSTATPRS, 3, "transistor '%s' ignored in circuit '%s'\n", scantrs->TRNAME, ptfig->NAME);
1600 scantrs->TRNAME=(char *)1, removed++; // marquage? pour remove
1601 }
1602 }
1603
1604 if (removed)
1605 {
1606 delflaggedloins(figins);
1607 delflaggedlotrs(figins, (char *)1);
1608 lofigchain (figins);
1609 }
1610 }
1611 for (ptcon = ptins->LOCON; ptcon; ptcon = ptcon->NEXT)
1612 if (ptcon->SIG->PRCN && gettabnode (ptcon->SIG->PRCN))
1613 freetable (ptcon->SIG);
1614
1615 /* Si un seul signal a un RC, on en cree un sur tous les autres */
1616
1617 for (ptcon = ptins->LOCON; ptcon; ptcon = ptcon->NEXT)
1618 if (ptcon->SIG->PRCN)
1619 break;
1620
1621 if (!ptcon)
1622 for (scanlosig = figins->LOSIG; scanlosig; scanlosig = scanlosig->NEXT)
1623 if (scanlosig->PRCN)
1624 break;
1625
1626 if (scanlosig || ptcon) {
1627 for (ptcon = ptins->LOCON; ptcon; ptcon = ptcon->NEXT) {
1628 if (!ptcon->SIG->PRCN/* || (ptcon->SIG->PRCN->PWIRE==NULL && ptcon->SIG->PRCN->PCTC==NULL)*/) {
1629 if (!ptcon->SIG->PRCN) addlorcnet (ptcon->SIG);
1630 ptptype = getptype( ptcon->SIG->USER, LOFIGCHAIN );
1631 for( scanchain = (chain_list*)ptptype->DATA ; scanchain ; scanchain = scanchain->NEXT ) {
1632 eptcon = (locon_list*)scanchain->DATA ;
1633 if( !eptcon->PNODE ) // inutile de le vérifier, mais bon...
1634 eptcon->PNODE = addnum( NULL, 1l );
1635 }
1636 nblorc++;
1637 }
1638
1639 if (gettabnode (ptcon->SIG->PRCN))
1640 freetable (ptcon->SIG);
1641 }
1642
1643 for (scanlosig = figins->LOSIG; scanlosig; scanlosig = scanlosig->NEXT) {
1644 if (!scanlosig->PRCN/* || (scanlosig->PRCN->PWIRE==NULL && scanlosig->PRCN->PCTC==NULL)*/) {
1645 if (!scanlosig->PRCN) addlorcnet (scanlosig);
1646 ptptype = getptype( scanlosig->USER, LOFIGCHAIN );
1647 for( scanchain = (chain_list*)ptptype->DATA ; scanchain ; scanchain = scanchain->NEXT ) {
1648 eptcon = (locon_list*)scanchain->DATA ;
1649 if( !eptcon->PNODE ) // inutile de le vérifier, mais bon...
1650 eptcon->PNODE = addnum( NULL, 1l );
1651 }
1652 nblorc++;
1653 }
1654 if (gettabnode (scanlosig->PRCN))
1655 freetable (scanlosig);
1656 }
1657 }
1658
1659 addcorresp (figins, ptins);
1660
1661 /* Au boulot */
1662 for (scanlosig = figins->LOSIG; scanlosig; scanlosig = scanlosig->NEXT) {
1663 if (iscache && scanlosig->PRCN && (scanlosig->PRCN->PWIRE || scanlosig->PRCN->PCTC))
1664 avt_errmsg(MBK_ERRMSG, "006", AVT_FATAL, ptfig->NAME);
1665
1666 if (scanlosig->TYPE == INTERNAL) {
1667 //---------NEW-------------
1668 keptoldsig=0;
1669 local_concat=concat;
1670
1671 if (MBK_HANDLE_GLOBAL_NODES && mbk_LosigIsGlobal(scanlosig) && sighasnorc(scanlosig))
1672 {
1673 if (globalht==NULL)
1674 {
1675 globalht=addht(10);
1676 for (newsig=ptfig->LOSIG; newsig!=NULL; newsig=newsig->NEXT)
1677 /*if (mbk_LosigIsGlobal(newsig))*/ addhtitem(globalht, getsigname(newsig), (long)newsig);
1678 }
1679 if ((key=gethtitem(globalht, getsigname(scanlosig)))!=EMPTYHT)
1680 {
1681 newsig=(losig_list *)key;
1682 if (sighasnorc(newsig))
1683 {
1684 keptoldsig=1; // do nothing
1685 }
1686 else
1687 {
1688 newsig = addlosig (ptfig, maxsig, NULL, INTERNAL);
1689 }
1690 }
1691 else
1692 {
1693 newsig = addlosig (ptfig, maxsig, NULL, INTERNAL);
1694 local_concat=NO;
1695 // addhtitem(globalht, getsigname(scanlosig), (long)newsig);
1696 }
1697 }
1698 //-------------
1699 else
1700 {
1701 newsig = addlosig (ptfig, maxsig, NULL, INTERNAL);
1702 }
1703
1704 lazy_duplosigalim (scanlosig, newsig);
1705 if (!keptoldsig)
1706 {
1707 mbk_dupvcardnodes(scanlosig, newsig);
1708 if ((ptptype=getptype(newsig->USER, MBK_VCARD_NODES))!=NULL)
1709 {
1710 chain_list *cl;
1711 vcardnodeinfo *vci;
1712 for (cl=(chain_list *)ptptype->DATA; ptptype; ptptype=ptptype->NEXT)
1713 {
1714 vci=(vcardnodeinfo *)cl->DATA;
1715 vci->name=concatname (insname, vci->name);
1716 }
1717 }
1718 }
1719
1720 if (!keptoldsig) newsig->FLAGS = 0;
1721
1722 if (!GROUP_MODE && (newsig->FLAGS & LFREBUILDCTC) == 0)
1723 {
1724 rebuildctc = addchain (rebuildctc, newsig);
1725 cntrebui++;
1726 }
1727
1728 newsig->FLAGS |= LFREBUILDCTC;
1729
1730 if (!keptoldsig)
1731 {
1732 maxsig++;
1733 newlosig++;
1734
1735 ptptype = newsig->USER = addptype (newsig->USER, LOFIGCHAIN, NULL);
1736
1737 /* concatene les nom si necessaire */
1738
1739 if (concat != NO && local_concat!=NO)
1740 for (scanchain = scanlosig->NAMECHAIN; scanchain; scanchain = scanchain->NEXT)
1741 scanchain->DATA = concatname (insname, (char *)(scanchain->DATA));
1742
1743 newsig->NAMECHAIN = scanlosig->NAMECHAIN;
1744 scanlosig->NAMECHAIN = NULL;
1745 if (globalht!=NULL) addhtitem(globalht, getsigname(newsig), (long)newsig);
1746 }
1747 else
1748 ptptype = getptype (newsig->USER, LOFIGCHAIN);
1749
1750 for (scanchain = getptype (scanlosig->USER, LOFIGCHAIN)->DATA; scanchain; scanchain = scanchain->NEXT) {
1751 ptcon = (locon_list *) (scanchain->DATA);
1752 if (!(keptoldsig && ptcon->TYPE==EXTERNAL))
1753 {
1754 ptcon->SIG = newsig;
1755 ptptype->DATA = (void *)addchain ((chain_list *) ptptype->DATA, ptcon);
1756 }
1757 }
1758
1759 if (scanlosig->PRCN) {
1760
1761 if (!keptoldsig)
1762 duplorcnet (newsig, scanlosig);
1763 else
1764 givelorcnet(newsig);
1765
1766 if (concat != NO)
1767 {
1768 lowire_list *nw;
1769 for (scanwire = scanlosig->PRCN->PWIRE; scanwire; scanwire = nw)
1770 {
1771 nw=scanwire->NEXT;
1772 if ((p0=getptype(scanwire->USER, RESINAME))!=NULL)
1773 {
1774 p0->DATA=concatname (insname, (char *)p0->DATA);
1775 if (mbk_CheckREGEX(&IGNORE_RESISTANCE, p0->DATA)!=0)
1776 {
1777 avt_log( LOGSTATPRS, 3, "resistor '%s' ignored in circuit '%s'\n", (char *)p0->DATA, ptfig->NAME);
1778 dellowire(scanlosig, scanwire->NODE1, scanwire->NODE2);
1779 }
1780 }
1781 }
1782 }
1783
1784 /* Duplication des CTC */
1785
1786 for (scanctc = scanlosig->PRCN->PCTC; scanctc; scanctc = nextscanctc) {
1787 nextscanctc=scanctc->NEXT;
1788 ptctc = (loctc_list *) scanctc->DATA;
1789 if (!ptctc) {
1790 avt_errmsg(MBK_ERRMSG, "008", AVT_ERROR, scanlosig->INDEX, insname);
1791 }
1792 if (concat != NO && ptctc->SIG1 == scanlosig)
1793 {
1794 if ((p0=getptype(ptctc->USER, MSL_CAPANAME))!=NULL)
1795 {
1796 p0->DATA=concatname (insname, (char *)p0->DATA);
1797 if (rcn_isCapaDiode(ptctc)) ic_or_id=&IGNORE_DIODE; else ic_or_id=&IGNORE_CAPACITANCE;
1798 if (mbk_CheckREGEX(ic_or_id, p0->DATA)!=0)
1799 {
1800 avt_log( LOGSTATPRS, 3, "capacitance '%s' ignored in circuit '%s'\n", (char *)p0->DATA, ptfig->NAME);
1801 delloctc(ptctc);
1802 continue;
1803 }
1804 }
1805 }
1806
1807 if (ptctc->SIG1 == scanlosig) {
1808 newsig->PRCN->PCTC = addchain (newsig->PRCN->PCTC, ptctc);
1809 ptctc->SIG1 = newsig;
1810 }
1811
1812 if (ptctc->SIG2 == scanlosig) {
1813 newsig->PRCN->PCTC = addchain (newsig->PRCN->PCTC, ptctc);
1814 ptctc->SIG2 = newsig;
1815 }
1816 }
1817 }
1818 }
1819 else {
1820
1821 /* cree la liste interf */
1822 interf = (struct st_interf *)AddHeapItem (&interf_heap);
1823 interf->base = 0;
1824 interf->next = NULL;
1825 interf->sig = scanlosig;
1826
1827
1828 scanlosig->FLAGS = 0;
1829 cl = getsigexternalconnectors (scanlosig);
1830 for (scanchain = cl; scanchain; scanchain = scanchain->NEXT) {
1831 ptcon = (locon_list *) scanchain->DATA;
1832 ptcon->DIRECTION = -1;
1833 IDLE_LOCON++;
1834 scanlocon = getcorrespinstanceconnector (ptcon);
1835 if (!scanlocon) {
1836 avt_errmsg(MBK_ERRMSG, "009", AVT_FATAL, ptcon->NAME, insname);
1837 }
1838
1839 scanlocon->DIRECTION = -1;
1840
1841 ptinterf = (struct st_interf *)AddHeapItem (&interf_heap);
1842 ptinterf->base = 0;
1843 ptinterf->next = interf;
1844 ptinterf->sig = scanlocon->SIG;
1845 interf = ptinterf;
1846
1847 if (!scanlocon->PNODE && ptcon->PNODE) {
1848 for (maxnode_itrf = 0, sn1 = ptcon->PNODE; sn1; sn1 = sn1->NEXT, maxnode_itrf++);
1849
1850 newnode_itrf = addlonode (scanlocon->SIG, NULL);
1851
1852 for (i = 1; i <= maxnode_itrf; i++)
1853 setloconnode (scanlocon, newnode_itrf);
1854 }
1855
1856 if (scanlocon->PNODE && !ptcon->PNODE) {
1857 for (maxnode_itrf = 0, sn1 = scanlocon->PNODE; sn1; sn1 = sn1->NEXT, maxnode_itrf++);
1858
1859 newnode_itrf = addlonode (ptcon->SIG, NULL);
1860
1861 for (i = 1; i <= maxnode_itrf; i++)
1862 setloconnode (ptcon, newnode_itrf);
1863 }
1864
1865 }
1866 {
1867 best = NULL;
1868 for (ptinterf = interf; ptinterf; ptinterf = ptinterf->next) {
1869 if (ptinterf->sig != scanlosig) {
1870 if (ptinterf->sig->FLAGS != 0) {
1871 best = ptinterf;
1872 break;
1873 }
1874 else
1875 best = ptinterf;
1876 }
1877 }
1878 ptinterf = best;
1879 }
1880
1881 if (ptinterf) {
1882 struct st_interf *tempptinterf;
1883 newsig = ptinterf->sig;
1884 for (tempptinterf = interf; tempptinterf; tempptinterf = tempptinterf->next)
1885 if (tempptinterf->sig != newsig)
1886 {
1887 lazy_duplosigalim (tempptinterf->sig, newsig);
1888 if (mbk_LosigIsVDD(tempptinterf->sig)) mbk_SetLosigVDD(newsig);
1889 else if (mbk_LosigIsVSS(tempptinterf->sig)) mbk_SetLosigVSS(newsig);
1890 }
1891 ptptype = getptype (newsig->USER, LOFIGCHAIN);
1892 if ((ptinterf->sig->FLAGS & LFCANDIDAT) == 0) {
1893 ptinterf->sig->FLAGS |= LFCANDIDAT;
1894 candidat_list = addchain (candidat_list, ptinterf->sig);
1895 if (!GROUP_MODE && (newsig->FLAGS & LFREBUILDCTC) == 0) {
1896 rebuildctc = addchain (rebuildctc, newsig);
1897 cntrebui++;
1898 }
1899
1900 newsig->FLAGS |= LFREBUILDCTC;
1901 }
1902 }
1903 else {
1904 newsig = addlosig (ptfig, maxsig, NULL, INTERNAL);
1905 lazy_duplosigalim (scanlosig, newsig);
1906 newsig->FLAGS = 0;
1907 if (!GROUP_MODE && (newsig->FLAGS & LFREBUILDCTC) == 0) {
1908 rebuildctc = addchain (rebuildctc, newsig);
1909 cntrebui++;
1910 }
1911
1912 newsig->FLAGS |= LFREBUILDCTC;
1913
1914
1915 maxsig++;
1916 newsig->USER = addptype (newsig->USER, LOFIGCHAIN, NULL);
1917 ptptype = newsig->USER;
1918 }
1919 if ((newsig->FLAGS & LFPOSTRAIT) == 0) {
1920 posttreatsig = addchain (posttreatsig, newsig);
1921 newsig->FLAGS |= LFPOSTRAIT;
1922 cntpost++;
1923 }
1924
1925 /* cree la liste contact */
1926 contact = NULL;
1927 if (newsig->PRCN)
1928 {
1929 nbinterf = newsig->PRCN->NBNODE;
1930 if (nbinterf<=1) nbinterf=2; //should always be >=2
1931 }
1932 else
1933 nbinterf = 1;
1934
1935
1936 cl = getsigexternalconnectors (scanlosig);
1937 for (scanchain = cl; scanchain; scanchain = scanchain->NEXT) {
1938 ptcon = (locon_list *) (scanchain->DATA);
1939 scanlocon = getcorrespinstanceconnector (ptcon);
1940 if (!scanlocon) {
1941 avt_errmsg(MBK_ERRMSG, "009", AVT_FATAL, ptcon->NAME, ptfig->NAME);
1942 }
1943 cleancorrespinstanceconnector (ptcon);
1944 if (scanlocon->PNODE || ptcon->PNODE) {
1945 for (sn1 = scanlocon->PNODE, sn2 = ptcon->PNODE; sn1 && sn2; sn1 = sn1->NEXT, sn2 = sn2->NEXT) {
1946 ptcontact = (struct st_contact *)AddHeapItem (&contact_heap);
1947
1948 ptcontact->next = contact;
1949 ptcontact->con1 = scanlocon;
1950 ptcontact->con2 = ptcon;
1951 ptcontact->node1 = sn1->DATA;
1952 ptcontact->node2 = sn2->DATA;
1953 if (scanlocon->SIG == newsig)
1954 ptcontact->interf = sn1->DATA;
1955 else {
1956 ptcontact->interf = nbinterf++;
1957 }
1958
1959 contact = ptcontact;
1960 }
1961
1962 if (scanlocon->PNODE->NEXT == NULL && sn2) {
1963 for (; sn2; sn2 = sn2->NEXT) {
1964 ptcontact = (struct st_contact *)AddHeapItem (&contact_heap);
1965 ptcontact->next = contact;
1966 ptcontact->con1 = scanlocon;
1967 ptcontact->con2 = ptcon;
1968 ptcontact->node1 = contact->node1;
1969 ptcontact->node2 = sn2->DATA;
1970 ptcontact->interf = contact->interf;
1971 contact = ptcontact;
1972 }
1973 }
1974 else if (sn1 || sn2) {
1975 avt_errmsg(MBK_ERRMSG, "010", AVT_FATAL, ptcon->NAME, figins->NAME);
1976 }
1977 }
1978 else {
1979 ptcontact = (struct st_contact *)AddHeapItem (&contact_heap);
1980
1981 ptcontact->next = contact;
1982 ptcontact->con1 = scanlocon;
1983 ptcontact->con2 = ptcon;
1984 ptcontact->node1 = 0;
1985 ptcontact->node2 = 0;
1986 ptcontact->interf = 0;
1987
1988 contact = ptcontact;
1989 }
1990 }
1991
1992 cleansigexternalconnectors (scanlosig);
1993 freechain (cl);
1994
1995 /* Met a jour le champs base des structures inter */
1996 if (interf->sig->PRCN) {
1997 if (!newsig->PRCN) {
1998 addlorcnet (newsig);
1999 nblorc++;
2000 }
2001 maxnode = nbinterf;
2002
2003 for (ptinterf = interf; ptinterf; ptinterf = ptinterf->next) {
2004 if (ptinterf->sig != newsig) {
2005 ptinterf->base = maxnode - 1;
2006 maxnode = maxnode + ptinterf->sig->PRCN->NBNODE - 1;
2007
2008 rcn_addcapa (newsig, rcn_getcapa (figins, ptinterf->sig));
2009 }
2010 else
2011 ptinterf->base = 0;
2012 }
2013 }
2014
2015 /* calcul le type de newsig */
2016
2017 for (ptinterf = interf; ptinterf; ptinterf = ptinterf->next)
2018 if (ptinterf->sig != scanlosig && ptinterf->sig->TYPE == EXTERNAL)
2019 break;
2020
2021 R=0;
2022 if (ptinterf)
2023 {
2024 if (newsig->TYPE == INTERNAL && !FLATTEN_KEEP_ALL_NAMES)
2025 {
2026 freechain(newsig->NAMECHAIN);
2027 newsig->NAMECHAIN=NULL;
2028 R=1;
2029 }
2030 newsig->TYPE = EXTERNAL;
2031 }
2032 else
2033 newsig->TYPE = INTERNAL;
2034
2035 /* met a jour le nom de newsig */
2036 A=(has_ignore_names==0 && newsig->NAMECHAIN == NULL && R==0);
2037 for (ptinterf = interf; ptinterf; ptinterf = ptinterf->next) {
2038 if (ptinterf->sig == newsig)
2039 continue;
2040
2041 if (A || has_ignore_names || FLATTEN_KEEP_ALL_NAMES == 1 || (ptinterf->sig!=scanlosig && (ptinterf->sig->TYPE==EXTERNAL || newsig->TYPE == INTERNAL)))
2042 {
2043 if (concat != NO) {
2044 if (ptinterf->sig == scanlosig)
2045 for (scanchain = ptinterf->sig->NAMECHAIN; scanchain; scanchain = scanchain->NEXT)
2046 {
2047 scanchain->DATA = concatname (insname, (char *)scanchain->DATA);
2048 }
2049 }
2050
2051 newsig->NAMECHAIN = append (ptinterf->sig->NAMECHAIN, newsig->NAMECHAIN);
2052 ptinterf->sig->NAMECHAIN = NULL;
2053
2054 if (has_ignore_names)
2055 {
2056 cl=NULL;
2057 for (scanchain = newsig->NAMECHAIN; scanchain; scanchain = scanchain->NEXT)
2058 {
2059 if (mbk_CheckREGEX(&IGNORE_NAMES, (char *)scanchain->DATA)==0 || (cl==NULL && scanchain->NEXT==NULL))
2060 cl=addchain(cl, scanchain->DATA);
2061 }
2062 freechain(newsig->NAMECHAIN);
2063 newsig->NAMECHAIN=cl;
2064 }
2065 }
2066 }
2067
2068 if (newsig->TYPE == INTERNAL && !FLATTEN_KEEP_ALL_NAMES && countchain(newsig->NAMECHAIN)>1)
2069 {
2070 char *bestname;
2071 bestname=getsigname(newsig);
2072 freechain(newsig->NAMECHAIN);
2073 newsig->NAMECHAIN=addchain(NULL, bestname);
2074 }
2075
2076 /* Pour chaque signal S de interf */
2077 for (ptinterf = interf; ptinterf; ptinterf = ptinterf->next) {
2078 if (ptinterf->sig == newsig)
2079 continue;
2080
2081 if ((ptinterf->sig->FLAGS & LFCANDIDAT) != 0)
2082 {
2083 ptinterf->sig->FLAGS &= ~LFCANDIDAT;
2084 candidat_list=delchaindata(candidat_list, ptinterf->sig);
2085 }
2086 /* Pour chaque connecteur C de S */
2087 for (scanchain =
2088 (chain_list *) (getptype (ptinterf->sig->USER, LOFIGCHAIN)->DATA);
2089 scanchain; scanchain = scanchain->NEXT) {
2090 ptcon = (locon_list *) (scanchain->DATA);
2091
2092 ptcontact = NULL;
2093 if (ptcon->DIRECTION == -1)
2094 for (ptcontact = contact; ptcontact; ptcontact = ptcontact->next)
2095 if (ptcon == ptcontact->con1 || ptcon == ptcontact->con2)
2096 break;
2097
2098 /* Si C n'est pas sur l'interface */
2099 if (!ptcontact) {
2100 ptptype->DATA = (void *)addchain ((chain_list *) ptptype->DATA, ptcon);
2101
2102 for (sn1 = ptcon->PNODE; sn1; sn1 = sn1->NEXT) {
2103 for (ptcontact = contact; ptcontact; ptcontact = ptcontact->next) {
2104 if (ptcontact->node1 == sn1->DATA && ptcontact->con1->SIG == ptcon->SIG)
2105 break;
2106 if (ptcontact->node2 == sn1->DATA && ptcontact->con2->SIG == ptcon->SIG)
2107 break;
2108 }
2109
2110 if (ptcontact)
2111 /* cas particulier : si un noeud appartient aussi a un
2112 * connecteur de l'interface */
2113 sn1->DATA = ptcontact->interf;
2114 else
2115 sn1->DATA = sn1->DATA + ptinterf->base;
2116 }
2117
2118 ptcon->SIG = newsig;
2119 for (sn1 = ptcon->PNODE; sn1; sn1 = sn1->NEXT)
2120 if (ptcon->SIG->PRCN->NBNODE <= sn1->DATA)
2121 ptcon->SIG->PRCN->NBNODE = sn1->DATA + 1;
2122 }
2123 }
2124
2125 if (ptinterf->sig->PRCN) {
2126 /* Pour chaque noeud de S, on calcule son nouvel index dans
2127 * un tableau newnode */
2128 newnode = mbkalloc (sizeof (int) * (ptinterf->sig->PRCN->NBNODE + 1));
2129 memset (newnode, 0, sizeof (int) * (ptinterf->sig->PRCN->NBNODE + 1));
2130
2131 for (ptcontact = contact; ptcontact; ptcontact = ptcontact->next) {
2132 if (ptinterf->sig == ptcontact->con1->SIG) {
2133 newnode[ptcontact->node1] = ptcontact->interf;
2134 }
2135 else if (ptinterf->sig == ptcontact->con2->SIG) {
2136 newnode[ptcontact->node2] = ptcontact->interf;
2137 }
2138 }
2139
2140 for (node1 = 1; node1 <= ptinterf->sig->PRCN->NBNODE; node1++)
2141 if (newnode[node1] == 0)
2142 newnode[node1] = node1 + ptinterf->base;
2143
2144 if ((ptptype=getptype(ptinterf->sig->USER, MBK_VCARD_NODES))!=NULL)
2145 {
2146 chain_list *cl;
2147 vcardnodeinfo *vci;
2148 for (cl=(chain_list *)ptptype->DATA; ptptype; ptptype=ptptype->NEXT)
2149 {
2150 vci=(vcardnodeinfo *)cl->DATA;
2151 if (vci->rcn<=ptinterf->sig->PRCN->NBNODE)
2152 mbk_addvcardnode(newsig, concatname (insname, vci->name), vci->value, newnode[vci->rcn]);
2153 }
2154 }
2155
2156 /* Pour chaque wire W de S */
2157 for (scanwire = ptinterf->sig->PRCN->PWIRE; scanwire; scanwire = scanwire->NEXT) {
2158 if ((p0=getptype(scanwire->USER, RESINAME))!=NULL)
2159 {
2160 name=concatname (insname, (char *)p0->DATA);
2161 if (mbk_CheckREGEX(&IGNORE_RESISTANCE, name)!=0)
2162 {
2163 avt_log( LOGSTATPRS, 3, "resistor '%s' ignored in circuit '%s'\n", name, ptfig->NAME);
2164 continue;
2165 }
2166 }
2167 curwire = addlowire (newsig,
2168 scanwire->FLAG,
2169 scanwire->RESI,
2170 scanwire->CAPA, newnode[scanwire->NODE1], newnode[scanwire->NODE2]
2171 );
2172 if (curwire!=NULL && p0!=NULL)
2173 curwire->USER=addptype(curwire->USER, RESINAME, name);
2174
2175 if (curwire && (p0 = getptype (scanwire->USER, OPT_PARAMS)))
2176 curwire->USER =
2177 addptype (curwire->USER, OPT_PARAMS,
2178 dupoptparamlst ((optparam_list *) p0->DATA));
2179 }
2180
2181 /* Pour chaque CTC de S */
2182 for (scanctc = ptinterf->sig->PRCN->PCTC; scanctc; scanctc = scanctc->NEXT) {
2183
2184 ptctc = (loctc_list *) scanctc->DATA;
2185
2186 if ((p0=getptype(ptctc->USER, MSL_CAPANAME))!=NULL && ptctc->SIG1 == ptinterf->sig)
2187 {
2188 name=concatname (insname, (char *)p0->DATA);
2189 if (rcn_isCapaDiode(ptctc)) ic_or_id=&IGNORE_DIODE; else ic_or_id=&IGNORE_CAPACITANCE;
2190 if (mbk_CheckREGEX(ic_or_id, name)!=0)
2191 {
2192 avt_log( LOGSTATPRS, 3, "capacitance '%s' ignored in circuit '%s'\n", name, ptfig->NAME);
2193 rcn_removecapa(newsig, ptctc->CAPA);
2194 delloctc(ptctc);
2195 continue;
2196 }
2197 p0->DATA=name;
2198 }
2199
2200 if (ptctc->SIG1 == ptinterf->sig) {
2201 ptctc->SIG1 = newsig;
2202 if (ptctc->NODE1)
2203 ptctc->NODE1 = newnode[ptctc->NODE1];
2204 }
2205 else {
2206 for (ctinterf = interf; ctinterf; ctinterf = ctinterf->next) {
2207 if (ptctc->SIG1 == ctinterf->sig) {
2208 ptctc->SIG1 = newsig;
2209
2210 if (ptctc->NODE1) {
2211 for (ptcontact = contact; ptcontact; ptcontact = ptcontact->next) {
2212 if ((ctinterf->sig == ptcontact->con1->SIG &&
2213 ptctc->NODE1 == ptcontact->node1) ||
2214 (ctinterf->sig == ptcontact->con2->SIG &&
2215 ptctc->NODE1 == ptcontact->node2)) {
2216 ptctc->NODE1 = ptcontact->interf;
2217 break;
2218 }
2219 }
2220 if (!ptcontact)
2221 ptctc->NODE1 = ptctc->NODE1 + ctinterf->base;
2222 break;
2223 }
2224 }
2225 }
2226 }
2227
2228 if (ptctc->SIG2 == ptinterf->sig) {
2229 ptctc->SIG2 = newsig;
2230 if (ptctc->NODE2)
2231 ptctc->NODE2 = newnode[ptctc->NODE2];
2232 }
2233 else {
2234 for (ctinterf = interf; ctinterf; ctinterf = ctinterf->next) {
2235 if (ptctc->SIG2 == ctinterf->sig) {
2236 ptctc->SIG2 = newsig;
2237
2238 if (ptctc->NODE2) {
2239 for (ptcontact = contact; ptcontact; ptcontact = ptcontact->next) {
2240 if ((ctinterf->sig == ptcontact->con1->SIG &&
2241 ptctc->NODE2 == ptcontact->node1) ||
2242 (ctinterf->sig == ptcontact->con2->SIG &&
2243 ptctc->NODE2 == ptcontact->node2)) {
2244 ptctc->NODE2 = ptcontact->interf;
2245 break;
2246 }
2247 }
2248 if (!ptcontact)
2249 ptctc->NODE2 = ptctc->NODE2 + ctinterf->base;
2250 break;
2251 }
2252 }
2253 }
2254 }
2255
2256 if (!ptctc) {
2257 avt_errmsg(MBK_ERRMSG, "011", AVT_ERROR, scanlosig->INDEX, insname);
2258 }
2259 newsig->PRCN->PCTC = addchain (newsig->PRCN->PCTC, ptctc);
2260 }
2261
2262 mbkfree (newnode);
2263 }
2264 }
2265
2266 for (ptinterf = interf; ptinterf; ptinterf = ptinterf->next) {
2267 if ((ptinterf->sig != scanlosig) && (ptinterf->sig != newsig)) {
2268 ptptype = getptype (ptinterf->sig->USER, LOFIGCHAIN);
2269 freechain ((chain_list *) ptptype->DATA);
2270 ptptype->DATA = NULL;
2271 if (ptinterf->sig->PRCN && ptinterf->sig->PRCN->PCTC) {
2272 freechain (ptinterf->sig->PRCN->PCTC);
2273 ptinterf->sig->PRCN->PCTC = NULL;
2274 }
2275 /*if (ptinterf->sig->FLAGS != 0)
2276 EXIT (5);*/
2277 dellosig (ptfig, ptinterf->sig->INDEX);
2278 }
2279 }
2280
2281 for (ptcontact = contact; ptcontact; ptcontact = (struct st_contact *)forfree) {
2282 forfree = ptcontact->next;
2283 DelHeapItem (&contact_heap, ptcontact);
2284 }
2285
2286 for (ptinterf = interf; ptinterf; ptinterf = (struct st_interf *)forfree) {
2287 forfree = ptinterf->next;
2288 DelHeapItem (&interf_heap, ptinterf);
2289 }
2290 }
2291 /* vire scanlosig */
2292 ptptype = getptype (scanlosig->USER, LOFIGCHAIN);
2293 freechain ((chain_list *) ptptype->DATA);
2294 ptptype->DATA = NULL;
2295
2296 if (scanlosig->PRCN && scanlosig->PRCN->PCTC) {
2297 freechain (scanlosig->PRCN->PCTC);
2298 scanlosig->PRCN->PCTC = NULL;
2299 }
2300
2301 dellosig (figins, scanlosig->INDEX);
2302
2303
2304 }
2305 if (all == 'Y') {
2306 delloins (ptfig, ptins->INSNAME);
2307 }
2308 else
2309 ptins->INSNAME = NULL; // flag pour delete
2310
2311 // zinaps le 14/1/2003
2312 if (FlattenOnCreateLOINS != NULL)
2313 for (scanins = figins->LOINS; scanins; scanins = scanins->NEXT)
2314 FlattenOnCreateLOINS (scanins);
2315
2316 if (FlattenOnCreateLOTRS != NULL)
2317 for (scantrs = figins->LOTRS; scantrs; scantrs = scantrs->NEXT)
2318 FlattenOnCreateLOTRS (scantrs);
2319
2320 for (scantrs = figins->LOTRS; scantrs; scantrs = scantrs->NEXT) {
2321 nbtr++;
2322 nblocon += 4;
2323 }
2324 for (scanins = figins->LOINS; scanins; scanins = scanins->NEXT) {
2325 locon_list *lc;
2326 nbins++;
2327 for (lc = scanins->LOCON; lc != NULL; lc = lc->NEXT)
2328 nblocon++;
2329 }
2330
2331 ptfig->LOINS = (loins_list *) append ((chain_list *) figins->LOINS, (chain_list *) ptfig->LOINS);
2332 ptfig->LOTRS = (lotrs_list *) append ((chain_list *) figins->LOTRS, (chain_list *) ptfig->LOTRS);
2333
2334 figins->LOINS = NULL;
2335 figins->LOTRS = NULL;
2336
2337 for (scanlocon = figins->LOCON; scanlocon; scanlocon = nextlocon) {
2338 nextlocon = scanlocon->NEXT;
2339 freenum (scanlocon->PNODE);
2340 delloconuser (scanlocon);
2341 mbkfree ((void *)scanlocon);
2342 }
2343 figins->LOCON = NULL;
2344
2345 mbk_free_NewBKSIG(&figins->BKSIG);
2346 /* for (ptptype = figins->BKSIG; ptptype; ptptype = ptptype->NEXT)
2347 mbkfree ((void *)ptptype->DATA);
2348 freeptype (figins->BKSIG);
2349 figins->BKSIG = NULL;*/
2350 figins->LOSIG = NULL;
2351
2352 freechain (figins->MODELCHAIN);
2353 figins->MODELCHAIN = NULL;
2354
2355 /* Les seules valeurs qui peuvent arriver sont : PTSIGSIZE */
2356
2357 dellofiguser (figins);
2358
2359 if (figins->MODELCHAIN ||
2360 figins->LOCON || figins->LOSIG || figins->BKSIG.TAB || figins->LOINS || figins->LOTRS || figins->USER) {
2361 avt_errmsg(MBK_ERRMSG, "012", AVT_WARNING, figins->NAME, figins->USER->TYPE);
2362 }
2363 mbkfree ((void *)figins);
2364
2365 if (all == 'N' && ptinslist == NULL)
2366 break;
2367
2368 if (IDLE_LOCON > 1000000) {
2369 IDLE_LOCON = 0;
2370 for (cl = candidat_list; cl != NULL; cl = cl->NEXT)
2371 cleanlofigchain_from_to_be_freed_connectors ((losig_list *) cl->DATA);
2372 freechain (candidat_list);
2373 candidat_list = NULL;
2374 }
2375 }
2376
2377 if (all == 'N')
2378 {
2379 int cnt = 0;
2380 for (cl = candidat_list; cl != NULL; cl = cl->NEXT, cnt++)
2381 cleanlofigchain_from_to_be_freed_connectors ((losig_list *) cl->DATA);
2382 freechain (candidat_list);
2383 delflaggedloins (ptfig);
2384 }
2385 else
2386 {
2387 for (cl = candidat_list; cl != NULL; cl = cl->NEXT)
2388 cleanlofigchain_from_to_be_freed_connectors ((losig_list *) cl->DATA);
2389 freechain (candidat_list);
2390 candidat_list = NULL;
2391 }
2392
2393 /* Post traitement sur les CTC dont un des noeuds est a 0 */
2394
2395 /* Variable de debuggage */
2396 verif = 0;
2397
2398 /* Regroupe les CTC en double */
2399 for (scanchain = posttreatsig; scanchain; scanchain = scanchain->NEXT) {
2400 scanlosig = (losig_list *) (scanchain->DATA);
2401
2402 scanlosig->FLAGS &= ~LFPOSTRAIT;
2403 if ((scanlosig->INDEX == 0) || (!scanlosig->PRCN) || !scanlosig->PRCN->PCTC)
2404 continue;
2405
2406 htab = addht (scanlosig->PRCN->NBNODE + 100);
2407
2408 for (scanctc = scanlosig->PRCN->PCTC; scanctc; scanctc = scanctc->NEXT) {
2409 ptctc = (loctc_list *) (scanctc->DATA);
2410
2411 if (ptctc->CAPA >= 0.0) {
2412 if (ptctc->SIG1 == scanlosig) {
2413 othersig = ptctc->SIG2;
2414 othernode = ptctc->NODE2;
2415 scanctcnode = ptctc->NODE1;
2416 }
2417 else {
2418 othersig = ptctc->SIG1;
2419 othernode = ptctc->NODE1;
2420 scanctcnode = ptctc->NODE2;
2421 }
2422 if (othersig == scanlosig && othernode == scanctcnode) {
2423 if (!GROUP_MODE && (othersig->FLAGS & LFREBUILDCTC) == 0) {
2424 rebuildctc = addchain (rebuildctc, othersig);
2425 }
2426 othersig->FLAGS |= LFREBUILDCTC;
2427 ptctc->CAPA = -1.0;
2428 verif = verif + 2;
2429 }
2430 else {
2431 key = othersig->INDEX << 18;
2432 key = (key | (othernode << 7));
2433 key = (key | scanctcnode);
2434
2435 if ((chainhtab = (chain_list *) gethtitem (htab, (void *)key)) == (chain_list *) EMPTYHT) {
2436 chainhtab = addchain (NULL, ptctc);
2437 addhtitem (htab, (void *)key, (long)chainhtab);
2438 }
2439 else {
2440 for (chainht = chainhtab; chainht; chainht = chainht->NEXT) {
2441 ptctc2 = (loctc_list *) (chainht->DATA);
2442
2443 if (ptctc2->CAPA < 0.0)
2444 continue;
2445
2446 if (((ptctc2->SIG1 == scanlosig && ptctc2->SIG2 == othersig) &&
2447 (ptctc2->NODE1 == scanctcnode && ptctc2->NODE2 == othernode)) ||
2448 ((ptctc2->SIG2 == scanlosig && ptctc2->SIG1 == othersig) &&
2449 (ptctc2->NODE2 == scanctcnode && ptctc2->NODE1 == othernode))) {
2450 if (!GROUP_MODE && (othersig->FLAGS & LFREBUILDCTC) == 0) {
2451 rebuildctc = addchain (rebuildctc, othersig);
2452 }
2453 othersig->FLAGS |= LFREBUILDCTC;
2454 // ptctc->CAPA += ptctc2->CAPA;
2455 // ptctc2->CAPA = -1.0;
2456 ptctc2->CAPA += ptctc->CAPA;
2457 if ((cnt=rcn_isCapaDiode(ptctc))!=0) rcn_setCapaDiode(ptctc2, cnt);
2458 ptctc->CAPA = -1.0;
2459 verif = verif + 2;
2460 }
2461 }
2462 if (ptctc->CAPA>0)
2463 chainhtab = addchain (chainhtab, ptctc);
2464 // chainhtab = addchain (chainhtab, ptctc);
2465 addhtitem (htab, (void *)key, (long)chainhtab);
2466 }
2467 }
2468 }
2469 }
2470
2471 scanhtkey( htab, 1, &nextkey, &nextitem );
2472 while( nextitem != EMPTYHT ) {
2473 freechain( (chain_list*)nextitem );
2474 scanhtkey( htab, 0, &nextkey, &nextitem );
2475 }
2476
2477 delht (htab);
2478 }
2479
2480
2481
2482 // Greg, le 30/09/02 : il faut assurer la cohérence des champs PREV dans les
2483 // ctc.... gros bordel.
2484
2485 if (!GROUP_MODE) {
2486 for (scanchain = rebuildctc; scanchain; scanchain = scanchain->NEXT) {
2487 newsig = (losig_list *) scanchain->DATA;
2488
2489 /* if( !getptype( newsig->USER, FLATTEN_POSTRAIT ) ) {
2490 newsig->USER = addptype( newsig->USER, FLATTEN_POSTRAIT, NULL );
2491 */
2492 /* if ((newsig->FLAGS & LFPOSTRAIT) == 0) {
2493 newsig->FLAGS |= LFPOSTRAIT;*/
2494 if (newsig->PRCN) {
2495 prevctc = NULL;
2496 for (scanctc = newsig->PRCN->PCTC; scanctc; scanctc = nextscanctc) {
2497 nextscanctc=scanctc->NEXT;
2498 ptctc = (loctc_list *) scanctc->DATA;
2499
2500 if (ptctc->SIG1==ptctc->SIG2)
2501 {
2502 // la ctc est presente 2 fois dans la liste
2503 // on l'enleve la 2eme fois
2504 if (ptctc->CAPA<-1.5) freeloctc(ptctc);
2505 else ptctc->CAPA=-2;
2506 scanctc->NEXT=NULL; freechain(scanctc);
2507 if (prevctc==NULL) newsig->PRCN->PCTC=nextscanctc;
2508 else prevctc->NEXT=nextscanctc;
2509 }
2510 else
2511 {
2512 if (ptctc->SIG1 == newsig)
2513 ptctc->PREV1 = prevctc;
2514 else
2515 ptctc->PREV2 = prevctc;
2516 prevctc = scanctc;
2517 }
2518 }
2519 // }
2520 }
2521 }
2522 }
2523 else {
2524 for (newsig = ptfig->LOSIG; newsig != NULL; newsig = newsig->NEXT) {
2525 if ((newsig->FLAGS & LFREBUILDCTC) != 0) {
2526 if (newsig->PRCN) {
2527 prevctc = NULL;
2528 for (scanctc = newsig->PRCN->PCTC; scanctc; scanctc = nextscanctc) {
2529 nextscanctc=scanctc->NEXT;
2530 ptctc = (loctc_list *) scanctc->DATA;
2531 if (ptctc->SIG1==ptctc->SIG2)
2532 {
2533 // la ctc est presente 2 fois dans la liste
2534 // on l'enleve la 2eme fois
2535 if (ptctc->CAPA<-1.5) freeloctc(ptctc);
2536 else ptctc->CAPA=-2;
2537 scanctc->NEXT=NULL; freechain(scanctc);
2538 if (prevctc==NULL) newsig->PRCN->PCTC=nextscanctc;
2539 else prevctc->NEXT=nextscanctc;
2540 }
2541 else
2542 {
2543 if (ptctc->SIG1 == newsig)
2544 ptctc->PREV1 = prevctc;
2545 else
2546 ptctc->PREV2 = prevctc;
2547 prevctc = scanctc;
2548 }
2549 }
2550 }
2551 }
2552 }
2553 }
2554
2555 /* On fait le menage en virant les CTC dont la capa vaut -1 */
2556
2557 for (scanchain = posttreatsig; scanchain; scanchain = scanchain->NEXT) {
2558 scanlosig = (losig_list *)scanchain->DATA;
2559 if ((scanlosig->INDEX == 0) || (!scanlosig->PRCN))
2560 continue;
2561
2562 for (scanctc = scanlosig->PRCN->PCTC; scanctc; scanctc = nextscanctc) {
2563 nextscanctc = scanctc->NEXT;
2564 ptctc = (loctc_list *)scanctc->DATA;
2565
2566 if (ptctc->CAPA < 0.0) delloctc(ptctc);
2567 }
2568 rcn_setcapa( scanlosig, rcn_calccapa( scanlosig ) );
2569 }
2570 freechain (posttreatsig);
2571
2572 for (ptcon=ptfig->LOCON; ptcon!=NULL; ptcon=ptcon->NEXT)
2573 {
2574 for (cl=ptcon->SIG->NAMECHAIN; cl!=NULL; cl=cl->NEXT)
2575 if (cl->DATA==ptcon->NAME) break;
2576 if (cl==NULL) ptcon->SIG->NAMECHAIN=addchain(ptcon->SIG->NAMECHAIN, ptcon->NAME);
2577 }
2578 #if DEBUGCTC
2579 if (dump) {
2580 chain_list *cl;
2581 for (newsig = ptfig->LOSIG; newsig != NULL; newsig = newsig->NEXT) {
2582 prevctc = NULL;
2583 for (scanctc = newsig->PRCN->PCTC; scanctc != NULL; scanctc = scanctc->NEXT) {
2584 ptctc = (loctc_list *) scanctc->DATA;
2585 if (ptctc->SIG1 == newsig && ptctc->PREV1 != prevctc) {
2586 printf ("**err(15) %s vs %s\n", newsig->NAMECHAIN->DATA, ptctc->SIG2->NAMECHAIN->DATA);
2587 break;
2588 }
2589 if (ptctc->SIG2 == newsig && ptctc->PREV2 != prevctc) {
2590 printf ("**err(16) %s vs %s\n", newsig->NAMECHAIN->DATA, ptctc->SIG1->NAMECHAIN->DATA);
2591 break;
2592 }
2593 if (!(ptctc->SIG1 == newsig || ptctc->SIG2 == newsig))
2594 exit (16);
2595 prevctc = scanctc;
2596 }
2597 }
2598 }
2599 #endif
2600 if (globalht!=NULL) delht(globalht);
2601 freechain (rebuildctc);
2602
2603 mbk_FreeREGEX(&IGNORE_TRANSISTOR);
2604 mbk_FreeREGEX(&IGNORE_INSTANCE);
2605 mbk_FreeREGEX(&IGNORE_RESISTANCE);
2606 mbk_FreeREGEX(&IGNORE_CAPACITANCE);
2607 mbk_FreeREGEX(&IGNORE_DIODE);
2608 mbk_FreeREGEX(&IGNORE_NAMES);
2609
2610 DeleteHeap (&interf_heap);
2611 DeleteHeap (&contact_heap);
2612 if (mc_ctx!=NULL) eqt_term(mc_ctx);
2613 }
2614
2615 void debugctc2 (lofig_list * ptfig)
2616 {
2617 losig_list *sig;
2618 chain_list *scanchain;
2619 loctc_list *ptctc;
2620
2621 printf ("Information sur la figure %s.\n", ptfig->NAME);
2622 for (sig = ptfig->LOSIG; sig; sig = sig->NEXT) {
2623 printf ("Signal %2ld (%16lX)\n", sig->INDEX, (long)sig);
2624 if (sig->PRCN) {
2625 for (scanchain = sig->PRCN->PCTC; scanchain; scanchain = scanchain->NEXT) {
2626 ptctc = (loctc_list *) (scanchain->DATA);
2627 printf (" CTC (%16lX) entre le signal %2ld (%16lX) et le signal %2ld (%16lX).\n",
2628 (long)ptctc, ptctc->SIG1->INDEX, (long)ptctc->SIG1, ptctc->SIG2->INDEX, (long)ptctc->SIG2);
2629 }
2630 }
2631 }
2632 }
2633
2634 void debugctc (losig_list * headlosig, int niveau)
2635 {
2636 losig_list *scanlosig;
2637 chain_list *scanctc;
2638 chain_list *scanctc2;
2639 loctc_list *ptctc;
2640
2641 /* Boucle de debuggage */
2642 for (scanlosig = headlosig; scanlosig; scanlosig = scanlosig->NEXT) {
2643 if (!scanlosig->PRCN)
2644 continue;
2645
2646 for (scanctc = scanlosig->PRCN->PCTC; scanctc; scanctc = scanctc->NEXT) {
2647 ptctc = (loctc_list *) (scanctc->DATA);
2648 if (getptype (ptctc->USER, FLATTEN_CTC)) {
2649 printf ("(%d) FLATTEN_CTC trouve dans la CTC (%16lX) entre %ld.%ld et %ld.%ld.\n",
2650 niveau, (long)ptctc, ptctc->SIG1->INDEX, ptctc->NODE1, ptctc->SIG2->INDEX, ptctc->NODE2);
2651 EXIT (-1);
2652 }
2653
2654 for (scanctc2 = (ptctc->SIG1 == scanlosig ? ptctc->SIG2 : ptctc->SIG1)->PRCN->PCTC;
2655 scanctc2; scanctc2 = scanctc2->NEXT) {
2656 if (scanctc2->DATA == ptctc)
2657 break;
2658 }
2659 if (!scanctc2) {
2660 printf ("(%d) CTC (%16lX) entre %ld:%ld et %ld:%ld sur signal %ld non trouvee sur l'autre signal.\n",
2661 niveau,
2662 (long)ptctc,
2663 ptctc->SIG1->INDEX, ptctc->NODE1, ptctc->SIG2->INDEX, ptctc->NODE2, scanlosig->INDEX);
2664 EXIT (-1);
2665 }
2666 }
2667 }
2668 }
2669
2670 /*******************************************************************************
2671 * function loadlofig *
2672 *******************************************************************************/
2673 void loadlofig (ptfig, name, mode)
2674 lofig_list *ptfig;
2675 char *name;
2676 char mode;
2677 {
2678 if (TRACE_MODE == 'Y')
2679 (void)fprintf (stdout, "--- mbk --- loadlofig : reading file %s.%s mode %c\n", name, IN_LO, mode);
2680 if ((!strcmp (IN_LO, "hns")) || (!strcmp (IN_LO, "fne"))
2681 || (!strcmp (IN_LO, "hdn")) || (!strcmp (IN_LO, "fdn")))
2682 vtiloadlofig (ptfig, name, mode);
2683 else if ((!strcmp (IN_LO, "al")) || (!strcmp (IN_LO, "alx")))
2684 alcloadlofig (ptfig, name, mode);
2685 else if (!strcmp (IN_LO, "spi") || !strcmp (IN_LO, "sp") || !strcmp (IN_LO, "cir"))
2686 spiceloadlofig (ptfig, name, mode);
2687 else if (!strcmp (IN_LO, "edi"))
2688 edifloadlofig (ptfig, name, mode);
2689 else if (!strcmp (IN_LO, "vst"))
2690 vhdlloadlofig (ptfig, name, mode);
2691 else if (!strcmp (IN_LO, "vhd"))
2692 vhdlloadlofig (ptfig, name, mode);
2693 else if (!strcmp (IN_LO, "vlg"))
2694 verilogloadlofig (ptfig, name, mode);
2695 else if (!strcmp (IN_LO, "v"))
2696 verilogloadlofig (ptfig, name, mode);
2697 else {
2698 (void)fflush (stdout);
2699 (void)fprintf (stderr, "*** mbk error ***\n");
2700 (void)fprintf (stderr, "MBK_IN_LO : '%s' unknown format\n", IN_LO);
2701 EXIT (1);
2702 }
2703
2704 if (TRACE_MODE == 'Y')
2705 (void)fprintf (stdout, "--- mbk --- loadlofig : done reading file %s.%s\n", name, IN_LO);
2706
2707 if (MBK_LOAD_PARA && mode == 'A') {
2708 if (TRACE_MODE == 'Y')
2709 (void)fprintf (stdout, "--- mbk --- loadlofig : reading file %s.%s\n", name, IN_PARASITICS);
2710
2711 if ((!strcmp (IN_PARASITICS, "spf")) || (!strcmp (IN_PARASITICS, "dspf")))
2712 spf_Annotate (ptfig);
2713 else if (!strcmp (IN_PARASITICS, "spef"))
2714 spef_Annotate (ptfig);
2715
2716 if (TRACE_MODE == 'Y')
2717 (void)fprintf (stdout, "--- mbk --- loadlofig : done reading file %s.%s\n", name, IN_PARASITICS);
2718 }
2719 }
2720
2721 /*******************************************************************************
2722 * function savelofig *
2723 *******************************************************************************/
2724
2725 void savelofig (ptfig)
2726 lofig_list *ptfig;
2727 {
2728 if ((!strcmp (OUT_LO, "hns")) || (!strcmp (OUT_LO, "fne"))
2729 || (!strcmp (OUT_LO, "hdn")) || (!strcmp (OUT_LO, "fdn")))
2730 vtisavelofig (ptfig);
2731 else if ((!strcmp (OUT_LO, "al")) || (!strcmp (OUT_LO, "alx")))
2732 alcsavelofig (ptfig);
2733 else if (!strcmp (OUT_LO, "spi") || !strcmp (OUT_LO, "sp") || !strcmp (OUT_LO, "cir"))
2734 spicesavelofig (ptfig);
2735 else if (!strcmp (OUT_LO, "edi"))
2736 edifsavelofig (ptfig);
2737 else if (!strcmp (OUT_LO, "vst"))
2738 vhdlsavelofig (ptfig,NULL);
2739 else if (!strcmp (OUT_LO, "vhd"))
2740 vhdlsavelofig (ptfig,NULL);
2741 else if (!strcmp (OUT_LO, "cct"))
2742 hilosavelofig (ptfig);
2743 else if (!strcmp (OUT_LO, "vlg"))
2744 vlogsavelofig (ptfig,NULL);
2745 else if (!strcmp (OUT_LO, "v"))
2746 vlogsavelofig (ptfig,NULL);
2747 else {
2748 (void)fflush (stdout);
2749 (void)fprintf (stderr, "*** mbk error ***\n");
2750 (void)fprintf (stderr, "MBK_OUT_LO : %s unknown format\n", OUT_LO);
2751 EXIT (1);
2752 }
2753 }
2754
2755 /*******************************************************************************
2756 * function rflattenlofig() *
2757 * flatten recursif sur une figure logique ptfig. *
2758 * concat permet de generer les cheminons (concat != 'N') *
2759 * la mise a plat s'effectue jusqu'au cellules du catalogue *
2760 * non comprises. *
2761 * catal = `y` ou catal=`Y` indique qu`il faut tenir compte du *
2762 * catalogue. Une autre valeur implique un flatten complet. *
2763 *******************************************************************************/
2764 static int IsInCatal (char *name, char catal)
2765 {
2766 if (catal && incatalog (name) && !incatalogdelete (name))
2767 return 1;
2768 return 0;
2769 }
2770
2771 static void hierrflattenlofig (lofig_list * ptlofig, AdvancedNameAllocator * ana, char concat, char catal)
2772 {
2773 loins_list *ptloins;
2774 chain_list *ptchain = NULL;
2775 chain_list *ptchainsav = NULL;
2776 chain_list *ptchainx = NULL;
2777
2778 for (ptloins = ptlofig->LOINS; ptloins; ptloins = ptloins->NEXT) {
2779 if (IsInCatal (ptloins->FIGNAME, catal)) {
2780 ptchainsav = addchain (ptchainsav, ptloins);
2781 }
2782 else {
2783 ptchain = addchain (ptchain, ptloins);
2784 }
2785 }
2786 ptlofig->LOINS = NULL;
2787
2788 for (ptchainx = ptchainsav; ptchainx != NULL; ptchainx = ptchainx->NEXT) {
2789 ptloins = (loins_list *) ptchainx->DATA;
2790 ptloins->NEXT = ptlofig->LOINS;
2791 ptlofig->LOINS = ptloins;
2792 }
2793 freechain (ptchainsav);
2794
2795 if (ptchain == NULL)
2796 return;
2797 for (ptchainx = ptchain; ptchainx != NULL; ptchainx = ptchainx->NEXT) {
2798 ptloins = (loins_list *) ptchainx->DATA;
2799 ptloins->NEXT = ptlofig->LOINS;
2800 ptlofig->LOINS = ptloins;
2801 }
2802 ptchain = reverse (ptchain);
2803
2804 flattenlofig_bypointer (ptlofig, ptchain, ana, concat);
2805
2806 freechain (ptchain);
2807
2808 hierrflattenlofig (ptlofig, ana, concat, catal);
2809 }
2810
2811 void rflattenlofig (ptfig, concat, catal)
2812 lofig_list *ptfig;
2813 char concat, catal;
2814 {
2815 AdvancedNameAllocator *ana;
2816
2817 catal = catal == NO ? 0 : 1;
2818
2819 ana = CreateAdvancedNameAllocator (CASE_SENSITIVE);
2820 hierrflattenlofig (ptfig, ana, concat, catal);
2821 flatten_setup_realname_from_hiername (ptfig, ana);
2822 FreeAdvancedNameAllocator (ana);
2823 }
2824
2825 /*******************************************************************************
2826 * function unflatOutsideList() *
2827 * Unflat the instances for which the name of the model is *
2828 * not in the list of models for which only a black box exists. *
2829 * This list is given in the file called MBK_BLACKBOX_NAME. *
2830 *******************************************************************************/
2831 lofig_list *unflatOutsideList (ptlofig, figname, insname)
2832 lofig_list *ptlofig;
2833 char *figname;
2834 char *insname;
2835 {
2836 lofig_list *ptnewfig;
2837 loins_list *ptloins;
2838 chain_list *inslist = NULL;
2839 char *name;
2840 int blacklisted = 0;
2841
2842 #ifdef AVERTEC_LICENSE
2843 if(avt_givetoken("HITAS_LICENSE_SERVER", "bbox")!=AVT_VALID_TOKEN) EXIT(1);
2844 #endif
2845
2846 for (ptloins = ptlofig->LOINS; ptloins; ptloins = ptloins->NEXT) {
2847 name = ptloins->FIGNAME;
2848 if (IsInBlackList(name)) blacklisted = 1;
2849 else inslist = addchain (inslist, ptloins);
2850 }
2851
2852 if (blacklisted) {
2853 ptnewfig = unflattenlofig (ptlofig, figname, insname, inslist);
2854 freechain (inslist);
2855 return ptnewfig;
2856 }
2857 else {
2858 freechain (inslist);
2859 return ptlofig;
2860 }
2861 }
2862
2863 /*******************************************************************************
2864 * function IsInBlackList() *
2865 *******************************************************************************/
2866
2867 int IsInBlackList (char *figname)
2868 {
2869 chain_list *cl;
2870 const char *pref="unused:";
2871
2872 if (!bl_loaded)
2873 {
2874 loadBlackList();
2875 bl_loaded = 1;
2876 }
2877
2878 if (BLACKLIST == NULL)
2879 return 0;
2880
2881 if (BLACKLIST_MATCH_RULE==NULL)
2882 {
2883 char *temp;
2884 BLACKLIST_MATCH_RULE=(mbk_match_rules *)mbkalloc(sizeof(mbk_match_rules));
2885 BLACKLIST_MATCH_RULE_UNUSED=(mbk_match_rules *)mbkalloc(sizeof(mbk_match_rules));
2886 mbk_CreateREGEX(BLACKLIST_MATCH_RULE, CASE_SENSITIVE, 1);
2887 mbk_CreateREGEX(BLACKLIST_MATCH_RULE_UNUSED, CASE_SENSITIVE, 1);
2888 for (cl=BLACKLIST; cl!=NULL; cl=cl->NEXT)
2889 {
2890 temp=(char *)cl->DATA;
2891 if (strncasecmp(temp, pref,strlen(pref))!=0)
2892 mbk_AddREGEX(BLACKLIST_MATCH_RULE, temp);
2893 else
2894 mbk_AddREGEX(BLACKLIST_MATCH_RULE_UNUSED, namealloc(&temp[strlen(pref)]));
2895 }
2896 }
2897
2898 if (mbk_CheckREGEX(BLACKLIST_MATCH_RULE_UNUSED, figname)) return 2;
2899 return mbk_CheckREGEX(BLACKLIST_MATCH_RULE, figname);
2900 }
2901
2902 /*******************************************************************************
2903 * function flatOutsideList() *
2904 * Flat the instances for which the name of the model is *
2905 * not in the list of models for which only a black box exists. *
2906 * This list is given in the file called MBK_BLACKBOX_NAME. *
2907 *******************************************************************************/
2908 static void hierFlatOutsideList (lofig_list * ptlofig, AdvancedNameAllocator * ana)
2909 {
2910 loins_list *ptloins;
2911 chain_list *ptchain = NULL;
2912 chain_list *ptchainsav = NULL;
2913 chain_list *ptchainx = NULL;
2914 int ret;
2915
2916 for (ptloins = ptlofig->LOINS; ptloins; ptloins = ptloins->NEXT) {
2917 ret=0;
2918 if (getptype(ptloins->USER, BBOX_AS_UNUSED)==NULL && (ret=IsInBlackList (ptloins->FIGNAME))==1) {
2919 ptchainsav = addchain (ptchainsav, ptloins);
2920 }
2921 else {
2922 ptchain = addchain (ptchain, ptloins);
2923 if (ret==2)
2924 {
2925 ptype_list *p0;
2926 char buf[512], buf1[512];
2927 if ((p0 = getptype (ptloins->USER, LF_HIERNAME_TO_NAMEALLOC)) != NULL)
2928 {
2929 AdvancedNameAllocName (ana, (int)(long)p0->DATA, buf);
2930 sprintf(buf1, "%s`%s",ptloins->FIGNAME,buf);
2931 }
2932 else
2933 sprintf(buf1, "%s`%s",ptloins->FIGNAME,ptloins->INSNAME);
2934 ptloins->USER=addptype(ptloins->USER, BBOX_AS_UNUSED, namealloc(buf1));
2935 }
2936 }
2937 }
2938 ptlofig->LOINS = NULL;
2939
2940 for (ptchainx = ptchainsav; ptchainx != NULL; ptchainx = ptchainx->NEXT) {
2941 ptloins = (loins_list *) ptchainx->DATA;
2942 ptloins->NEXT = ptlofig->LOINS;
2943 ptlofig->LOINS = ptloins;
2944 }
2945 freechain (ptchainsav);
2946
2947 if (ptchain == NULL)
2948 {
2949 ptype_list *ptype;
2950 eqt_ctx *mc_ctx = NULL;
2951 ptype = getptype (ptlofig->USER, PARAM_CONTEXT);
2952 flatten_parameters (ptlofig, NULL, ptype ? (eqt_param *) ptype->DATA : NULL , 0, 0, 0, 0, 0, 0, &mc_ctx);
2953 if (mc_ctx!=NULL) eqt_term(mc_ctx);
2954 return;
2955 }
2956 for (ptchainx = ptchain; ptchainx != NULL; ptchainx = ptchainx->NEXT) {
2957 ptloins = (loins_list *) ptchainx->DATA;
2958 ptloins->NEXT = ptlofig->LOINS;
2959 ptlofig->LOINS = ptloins;
2960 }
2961 ptchain = reverse (ptchain);
2962
2963 flattenlofig_bypointer (ptlofig, ptchain, ana, 'Y');
2964
2965 freechain (ptchain);
2966
2967 hierFlatOutsideList (ptlofig, ana);
2968 }
2969
2970 static int cntchain (void *cls)
2971 {
2972 int c = 0;
2973 chain_list *cl = (chain_list *) cls;
2974 while (cl != NULL) {
2975 c++;
2976 cl = cl->NEXT;
2977 }
2978 return c;
2979
2980 }
2981 static int cntoptparam (ptype_list * p, long num)
2982 {
2983 if ((p = getptype (p, num)) != NULL)
2984 return cntchain (p->DATA);
2985 return 0;
2986 }
2987
2988 void sizeoflofig (lofig_list * lf)
2989 {
2990 long nbcon = 0;
2991 long nbtr = 0;
2992 long nbins = 0;
2993 long nbsig = 0;
2994 long nbnum = 0;
2995 long _nbchain = 0;
2996 long _nbptype = 0;
2997 long nbprcn = 0;
2998 long nbopt = 0;
2999 long a, b, c, d;
3000 long nbvss = 0, nbvdd = 0;
3001
3002 locon_list *lc;
3003 lotrs_list *lt;
3004 loins_list *li;
3005 losig_list *ls;
3006 ptype_list *p;
3007
3008
3009 for (lc = lf->LOCON; lc != NULL; lc = lc->NEXT) {
3010 nbcon++;
3011 _nbptype += cntchain (lc->USER);
3012 nbnum += cntchain (lc->PNODE);
3013 _nbchain += cntoptparam (lc->USER, PNODENAME);
3014 }
3015 for (lt = lf->LOTRS; lt != NULL; lt = lt->NEXT) {
3016 nbtr++;
3017 _nbptype += cntchain (lt->USER);
3018 nbcon += 3;
3019 nbnum += cntchain (lt->GRID->PNODE);
3020 nbnum += cntchain (lt->SOURCE->PNODE);
3021 nbnum += cntchain (lt->DRAIN->PNODE);
3022 _nbptype += cntchain (lt->GRID->USER);
3023 _nbptype += cntchain (lt->SOURCE->USER);
3024 _nbptype += cntchain (lt->DRAIN->USER);
3025 _nbchain += cntoptparam (lt->GRID->USER, PNODENAME);
3026 _nbchain += cntoptparam (lt->SOURCE->USER, PNODENAME);
3027 _nbchain += cntoptparam (lt->DRAIN->USER, PNODENAME);
3028 if (lt->BULK) {
3029 nbcon++;
3030 nbnum += cntchain (lt->BULK->PNODE);
3031 _nbptype += cntchain (lt->BULK->USER);
3032 _nbchain += cntoptparam (lt->BULK->USER, PNODENAME);
3033 }
3034 nbopt += cntoptparam (lt->USER, OPT_PARAMS);
3035 }
3036 for (li = lf->LOINS; li != NULL; li = li->NEXT) {
3037 nbins++;
3038 _nbptype += cntchain (li->USER);
3039 for (lc = li->LOCON; lc != NULL; lc = lc->NEXT) {
3040 nbcon++;
3041 _nbptype += cntchain (lc->USER);
3042 nbnum += cntchain (lc->PNODE);
3043 _nbchain += cntoptparam (lc->USER, PNODENAME);
3044 }
3045 nbopt += cntoptparam (li->USER, OPT_PARAMS);
3046 }
3047 for (ls = lf->LOSIG; ls != NULL; ls = ls->NEXT) {
3048 nbsig++;
3049 _nbptype += cntchain (ls->USER);
3050 if (ls->PRCN)
3051 nbprcn++;
3052 if ((p = getptype (ls->USER, LOFIGCHAIN)) != NULL)
3053 _nbchain += cntchain (p->DATA);
3054 _nbchain += cntchain (ls->NAMECHAIN);
3055 if (mbk_LosigIsVSS(ls))
3056 nbvss++;
3057 if (mbk_LosigIsVDD(ls))
3058 nbvdd++;
3059 }
3060 printf ("reports:\nnblocon=%ld (%ldk)\n", nbcon, (sizeof (locon_list) * nbcon) / 1024);
3061 printf ("nbtr=%ld (%ldk)\n", nbtr, (sizeof (lotrs_list) * nbtr) / 1024);
3062 printf ("nbins=%ld (%ldk)\n", nbins, (sizeof (loins_list) * nbins) / 1024);
3063 printf ("nbsig=%ld (%ldk)\n", nbsig, (sizeof (losig_list) * nbsig) / 1024);
3064 printf ("nbnum=%ld (%ldk)\n", nbnum, (sizeof (num_list) * nbnum) / 1024);
3065 printf ("nbchain=%ld (%ldk)\n", _nbchain, (sizeof (chain_list) * _nbchain) / 1024);
3066 printf ("nbptype=%ld (%ldk)\n", _nbptype, (sizeof (ptype_list) * _nbptype) / 1024);
3067 printf ("nblorc=%ld (%ldk)\n", nbprcn, (sizeof (lorcnet_list) * nbprcn) / 1024);
3068 printf ("nbopt=%ld (%ldk)\n", nbopt, (sizeof (optparam_list) * nbopt) / 1024);
3069 printf ("total=%ldk\n", a = ((sizeof (locon_list) * nbcon) +
3070 (sizeof (lotrs_list) * nbtr) +
3071 (sizeof (loins_list) * nbins) +
3072 (sizeof (losig_list) * nbsig) +
3073 (sizeof (num_list) * nbnum) +
3074 (sizeof (chain_list) * _nbchain) +
3075 (sizeof (ptype_list) * _nbptype) +
3076 (sizeof (lorcnet_list) * nbprcn) +
3077 (sizeof (optparam_list) * nbopt)
3078 ) / 1024);
3079 #ifdef BASE_STAT
3080 printf (" freechain(%ldk) + freeptype(%ldk) + num(%ldk)\n", b = (i_nbchain * sizeof (chain_list)) / 1024, c = (i_nbptype * sizeof (ptype_list)) / 1024, d = (i_nbnum * sizeof (num_list)) / 1024);
3081 #else
3082 b=c=d=0;
3083 #endif
3084 printf ("FINAL: %ldk\n", a + b + c + d);
3085 printf (" %ld VSS, %ld VDD signals\n", nbvss, nbvdd);
3086 }
3087
3088 /*******************************************************************************
3089 * function loadBlackList() *
3090 *******************************************************************************/
3091
3092 void
3093 loadBlackList()
3094 {
3095 FILE *fpBlackBox;
3096 char buffer[1024];
3097
3098 fpBlackBox = mbkfopen (MBK_BBOX_NAME, NULL, "r");
3099 if (fpBlackBox == NULL) {
3100 return;
3101 }
3102
3103 BLACKLIST = NULL; //addht (10);
3104 while (!feof (fpBlackBox)) {
3105 if (fscanf (fpBlackBox, "%s\n", buffer) != 0) {
3106 BLACKLIST=addchain(BLACKLIST, namealloc (buffer));
3107 }
3108 }
3109 fclose (fpBlackBox);
3110 }
3111
3112 void SetBlackList(chain_list *list)
3113 {
3114 deleteBlackList();
3115
3116 BLACKLIST = NULL;
3117 while (list!=NULL) {
3118 BLACKLIST=addchain(BLACKLIST, namealloc((char *)list->DATA));
3119 list=list->NEXT;
3120 }
3121 bl_loaded=1;
3122 }
3123
3124 void
3125 deleteBlackList()
3126 {
3127 if (BLACKLIST_MATCH_RULE!=NULL)
3128 {
3129 mbk_FreeREGEX(BLACKLIST_MATCH_RULE);
3130 mbkfree(BLACKLIST_MATCH_RULE);
3131 BLACKLIST_MATCH_RULE=NULL;
3132 }
3133
3134 freechain(BLACKLIST);
3135 BLACKLIST=NULL;
3136 }
3137
3138 /*******************************************************************************
3139 * function flatOutsideList() *
3140 *******************************************************************************/
3141
3142 lofig_list *flatOutsideList (ptlofig)
3143 lofig_list *ptlofig;
3144 {
3145 AdvancedNameAllocator *ana;
3146
3147 #ifdef AVERTEC_LICENSE
3148 if(avt_givetoken("HITAS_LICENSE_SERVER", "bbox")!=AVT_VALID_TOKEN) EXIT(1);
3149 #endif
3150
3151 ana = CreateAdvancedNameAllocator (CASE_SENSITIVE);
3152 hierFlatOutsideList (ptlofig, ana);
3153
3154 flatten_setup_realname_from_hiername (ptlofig, ana);
3155
3156 FreeAdvancedNameAllocator (ana);
3157
3158 return ptlofig;
3159 }
3160 /*
3161 static locon_list *getextlocon (ptsig)
3162 losig_list *ptsig;
3163 {
3164 chain_list *loconchain;
3165 locon_list *ptlocon;
3166 chain_list *ptchain;
3167
3168 if (ptsig->TYPE != 'E')
3169 return NULL;
3170 loconchain = (chain_list *) getptype (ptsig->USER, LOFIGCHAIN)->DATA;
3171 for (ptchain = loconchain; ptchain; ptchain = ptchain->NEXT) {
3172 ptlocon = (locon_list *) ptchain->DATA;
3173 if (ptlocon->TYPE == EXTERNAL)
3174 return ptlocon;
3175 }
3176 return NULL;
3177 }
3178 */
3179 /*
3180 UNFLATLOFIG
3181
3182 II. Algorithme
3183 --------------
3184
3185 1. On fait un LOFIGCHAIN sur 'ptfig'.
3186
3187 2. On veut construire deux 'chain_list' :
3188 LI : signaux internes a la nouvelle figure
3189 LX : signaux externes a la nouvelle figure
3190
3191 Pour la figure 'ptfig', on parcourt la liste des signaux :
3192 Pour chaque signal, on parcourt la liste des connecteurs qui lui
3193 sont associes (par LOFIGCHAIN):
3194 * Si AUCUN connecteur n'appartient a une instance presente dans
3195 la liste 'list', on passe au signal suivant (pas d'insertion)
3196
3197 * Sinon, si TOUS les connecteurs appartiennent a une instance
3198 presente dans la liste 'list', le signal est insere dans la
3199 liste LI
3200 * Sinon, le signal est insere dans la liste LX
3201 (au moins un connecteur n'appartient pas a la nouvelle figure)
3202
3203 3. On construit la nouvelle figure. Il faut creer :
3204 - une liste des signaux
3205 - une liste des connecteurs externes
3206 - une liste des instances, chacune contenant une liste de connecteurs
3207
3208 a. liste des signaux
3209 on parcourt la liste LI et la liste LX : on ajoute chaque signal a
3210 la liste des signaux de la nouvelle figure.
3211 On construit une structure ptype (de nom UNFLATLOFIG), donnant a
3212 chaque signal de LI ou LX un pointeur vers le signal cree dans la
3213 nouvelle figure.
3214
3215 b. liste des connecteurs externes
3216 on parcourt la liste LX :
3217 pour chaque signal, on cherche le premier connecteur interne (a la
3218 nouvelle figure) et le premier connecteur externe (a la nouvelle
3219 figure), de preference un terminal de la figure pere: s'il en
3220 existe un (terminal) on prend celui-la, sinon on prend le
3221 premier externe a la nouvelle figure, mais non terminal dans
3222 la figure pere.
3223 On ajoute un connecteur externe a la nouvelle figure. Il pointe
3224 sur le signal courant (dans la nouvelle). Sa direction est:
3225 - si le connecteur n'appartenant pas a la nouvelle figure est
3226 un terminal du pere (externe), le nouveau connecteur prend la
3227 direction de ce terminal.
3228 - si le connecteur n'appartenant pas a la nouvelle figure est un
3229 connecteur d'instance, le nouveau connecteur prend la direction
3230 du premier connecteur INTERNE a la nouvelle figure trouve
3231 precedemment.
3232 Le nom du nouveau connecteur est:
3233 - le nom du signal auquel il est connecte si ce dernier en a un.
3234 - sinon :
3235 . si le premier connecteur n'appartenant pas a la nouvelle
3236 figure est un terminal, le nouveau prend ce nom,
3237 . si le premier connecteur n'appartenant pas a la nouvelle
3238 figure est un connecteur d'instance, le nouveau prend le
3239 nom du connecteur INTERNE a la nouvelle figure (comme pour
3240 la direction).
3241 Dans tous les cas, on concatene au nom un compteur (comptant le
3242 nombre de connecteurs externes crees) pour assurer l'unicite.
3243
3244 c. liste des instances
3245 on parcourt la liste 'list' :
3246 on insere chaque instance dans la liste d'instances de la nouvelle
3247 figure. Pour chaque connecteur d'une instance de 'list', on
3248 ajoute un connecteur dans la liste des connecteurs de l'instance
3249 dans la nouvelle figure, dont le signal dans la nouvelle figure est
3250 obtenu en consultant la structure ptype du signal dans la figure pere.
3251 Les connecteurs prennent les directions des connecteurs dans les
3252 instances de la figure pere.
3253
3254 4. On modifie la figure pere.
3255 On instancie la nouvelle figure.
3256 On detruit les signaux internes (LI).
3257 On detruit les instances de la liste 'list'.
3258 */
3259 /*******************************************************************************
3260 * function unflattenlofig *
3261 *******************************************************************************/
3262 lofig_list *unflattenlofig (ptfig, figname, insname, list)
3263 lofig_list *ptfig;
3264 char *figname;
3265 char *insname;
3266 chain_list *list;
3267 {
3268 lofig_list *newlofig = NULL;
3269 chain_list *li_head = NULL, *lx_head = NULL, *ptchain, *ptchain1;
3270 chain_list *loconchain, *ptnextchain, *ptprevchain;
3271 chain_list *outconchain = NULL;
3272 chain_list *sigchain = NULL;
3273 chain_list *savechain = NULL;
3274 chain_list *ctctodelete = NULL;
3275 losig_list *ptlosig, *newlosig;
3276 losig_list *vss_sig = NULL;
3277 losig_list *father_vss = NULL;
3278 losig_list *ptprevsig, *ptnextsig;
3279 losig_list *ptctcsig;
3280 losig_list *ptsource, *ptdrain, *ptgrid, *ptbulk;
3281 loctc_list *ptctc;
3282 num_list *ptnum;
3283 num_list *loconnodes = NULL, *toplevelnodes = NULL;
3284 loins_list *ptloins, *newloins;
3285 locon_list *ptlocon, *newlocon;
3286 locon_list *intlocon, *extlocon, *translocon;
3287 lotrs_list *ptlotrs, *newlotrs;
3288 ptype_list *ptuser;
3289 long *nodetab = NULL;
3290 long countnode = 0;
3291 long vss_node = 0, father_vss_node = 0;
3292 char loconname[BUFSIZE];
3293 char *name, *delete_flag;
3294 char locondir;
3295 int foundterm;
3296 int onvsssig, coupledvsssig;
3297 int i;
3298
3299 if (ptfig == NULL)
3300 return NULL;
3301 lofigchain (ptfig);
3302
3303 /* mark instances */
3304 for (ptchain = list; ptchain != NULL; ptchain = ptchain->NEXT) {
3305 ptloins = (loins_list *) ptchain->DATA;
3306 ptloins->USER = addptype (ptloins->USER, UNFLATLOFIG, NULL);
3307 }
3308
3309 /* scan signals:
3310 construct LI and LX. */
3311 for (ptlosig = ptfig->LOSIG; ptlosig != NULL; ptlosig = ptlosig->NEXT) {
3312 int found_int = 0, found_ext = 0;
3313
3314 /* scan connectors of signal */
3315 loconchain = (chain_list *) getptype (ptlosig->USER, LOFIGCHAIN)->DATA;
3316 for (; loconchain; loconchain = loconchain->NEXT) {
3317 ptlocon = (locon_list *) (loconchain->DATA);
3318 if (ptlocon->TYPE == 'T')
3319 found_int++;
3320 else if (ptlocon->TYPE!='I' || (ptlocon->TYPE=='I' && getptype (((loins_list *) ptlocon->ROOT)->USER, UNFLATLOFIG) == NULL))
3321 found_ext++;
3322 else
3323 found_int++;
3324 }
3325 if (found_ext != 0) { /* potentially external vss for top figure */
3326 if (mbk_LosigIsVSS(ptlosig)) father_vss = ptlosig;
3327 }
3328 if (found_int == 0) {
3329 if (mbk_LosigIsVSS(ptlosig)) father_vss = ptlosig; /* potentially internal vss for top figure */
3330 continue; /* no insertion */
3331 }
3332 if (found_ext == 0) {
3333 li_head = addchain (li_head, (void *)(ptlosig)); /* insert LI */
3334 }
3335 else {
3336 lx_head = addchain (lx_head, (void *)(ptlosig)); /* insert LX */
3337 }
3338 } /* endfor ptlosig */
3339
3340 /***** add new figure : */
3341 newlofig = addlofig (figname);
3342
3343 /* create signals list */
3344 for (ptchain = li_head; ptchain != NULL; ptchain = ptchain->NEXT) {
3345 ptlosig = (losig_list *)ptchain->DATA;
3346 newlosig = duplosig(ptlosig, newlofig);
3347 newlosig->NEXT = newlofig->LOSIG;
3348 newlofig->LOSIG = newlosig;
3349 newlosig->TYPE = INTERNAL;
3350 if (mbk_LosigIsVSS (ptlosig)) vss_sig = newlosig;
3351 newlosig->PRCN = ptlosig->PRCN;
3352 ptlosig->USER = addptype (ptlosig->USER, UNFLATLOFIG, newlosig);
3353 }
3354 for (ptchain = lx_head; ptchain != NULL; ptchain = ptchain->NEXT) {
3355 ptlosig = (losig_list *)ptchain->DATA;
3356 newlosig = duplosig(ptlosig, newlofig);
3357 newlosig->NEXT = newlofig->LOSIG;
3358 newlofig->LOSIG = newlosig;
3359 newlosig->TYPE = EXTERNAL;
3360 if (mbk_LosigIsVSS (ptlosig)) vss_sig = newlosig;
3361 newlosig->PRCN = ptlosig->PRCN;
3362 ptlosig->USER = addptype (ptlosig->USER, UNFLATLOFIG, newlosig);
3363 }
3364
3365 /* obtain ground node for crosstalk capacitances */
3366 if (vss_sig == NULL) {
3367 vss_sig = addlosig(newlofig, newlofig->BKSIG.maxindex + 1, addchain(NULL, namealloc("0")), INTERNAL);
3368 mbk_SetLosigVSS(vss_sig);
3369 }
3370 if (father_vss == NULL) {
3371 father_vss = addlosig(ptfig, ptfig->BKSIG.maxindex + 1, addchain(NULL, namealloc("0")), INTERNAL);
3372 mbk_SetLosigVSS(father_vss);
3373 }
3374 /* set the node to 1 if nodes exist else 0 !!! Check consequences */
3375 if (vss_sig->PRCN == NULL)
3376 vss_node = 0;
3377 else if (vss_sig->PRCN->NBNODE == 0)
3378 vss_node = 0;
3379 else
3380 vss_node = 1;
3381 if (father_vss->PRCN == NULL)
3382 father_vss_node = 0;
3383 else if (father_vss->PRCN->NBNODE == 0)
3384 father_vss_node = 0;
3385 else
3386 father_vss_node = 1;
3387
3388 /* update crosstalk capacitances */
3389 sigchain = NULL;
3390 for (ptlosig = newlofig->LOSIG; ptlosig; ptlosig = ptlosig->NEXT) {
3391 if (ptlosig->PRCN != NULL) {
3392 for (ptchain = ptlosig->PRCN->PCTC; ptchain; ptchain = ptnextchain) {
3393 ptnextchain = ptchain->NEXT;
3394 ptctc = (loctc_list *) ptchain->DATA;
3395 ptctcsig = ptctc->SIG1;
3396 onvsssig = 0;
3397 coupledvsssig = 0;
3398 if (getptype (ptctcsig->USER, RCN_REPORTED) == NULL) {
3399 if ((ptuser = getptype (ptctcsig->USER, UNFLATLOFIG)) == NULL) {
3400 if (ptctcsig->PRCN != NULL) { /* list of ctc signals to update */
3401 for (ptchain1 = savechain; ptchain1; ptchain1 = ptchain1->NEXT) {
3402 if (ptchain1->DATA == ptctcsig)
3403 break;
3404 }
3405 if (ptchain1 == NULL)
3406 savechain = addchain (savechain, ptctcsig);
3407 }
3408 if (mbk_LosigIsVSS(ptctcsig)) onvsssig = 1;
3409 if (!onvsssig) { /* add new ctc to top figure */
3410 addloctc (ptctcsig, ptctc->NODE1, father_vss, father_vss_node, ptctc->CAPA);
3411 }
3412 if (mbk_LosigIsVSS(ptctc->SIG2)) coupledvsssig = 1;
3413 if (!coupledvsssig) { /* problem if SIG2 == vss_sig */
3414 ptctc->SIG1 = vss_sig;
3415 ptctc->NODE1 = vss_node;
3416 if (vss_sig->PRCN != NULL) {
3417 vss_sig->PRCN->PCTC = addchain (vss_sig->PRCN->PCTC, ptctc);
3418 }
3419 }
3420 else { /* ctc must be completely removed */
3421 if (ptctc->SIG1->PRCN != NULL) { /* list of ctc signals to update */
3422 for (ptchain1 = savechain; ptchain1; ptchain1 = ptchain1->NEXT) {
3423 if (ptchain1->DATA == ptctc->SIG1)
3424 break;
3425 }
3426 if (ptchain1 == NULL)
3427 savechain = addchain (savechain, ptctc->SIG1);
3428 }
3429 if (ptctc->SIG2->PRCN != NULL) { /* list of ctc signals to update */
3430 for (ptchain1 = savechain; ptchain1; ptchain1 = ptchain1->NEXT) {
3431 if (ptchain1->DATA == ptctc->SIG2)
3432 break;
3433 }
3434 if (ptchain1 == NULL)
3435 savechain = addchain (savechain, ptctc->SIG2);
3436 }
3437 ptctc->SIG1 = NULL;
3438 ptctc->SIG2 = NULL;
3439 ctctodelete = addchain (ctctodelete, ptctc);
3440 }
3441 }
3442 else {
3443 ptctc->SIG1 = (losig_list *) ptuser->DATA;
3444 }
3445 if (ptctc->SIG1 != NULL) {
3446 ptctc->SIG1->USER = addptype (ptctc->SIG1->USER, RCN_REPORTED, NULL);
3447 sigchain = addchain (sigchain, ptctc->SIG1);
3448 }
3449 }
3450 ptctcsig = ptctc->SIG2;
3451 if (ptctcsig == NULL)
3452 continue;
3453 onvsssig = 0;
3454 coupledvsssig = 0;
3455 if (getptype (ptctcsig->USER, RCN_REPORTED) == NULL) {
3456 if ((ptuser = getptype (ptctcsig->USER, UNFLATLOFIG)) == NULL) {
3457 if (ptctcsig->PRCN != NULL) { /* list of ctc signals in top figure */
3458 for (ptchain1 = savechain; ptchain1; ptchain1 = ptchain1->NEXT) {
3459 if (ptchain1->DATA == ptctcsig)
3460 break;
3461 }
3462 if (ptchain1 == NULL)
3463 savechain = addchain (savechain, ptctcsig);
3464 }
3465 if (mbk_LosigIsVSS(ptctcsig)) onvsssig = 1;
3466 if (!onvsssig) { /* add new ctc to top figure */
3467 addloctc (ptctcsig, ptctc->NODE1, father_vss, father_vss_node, ptctc->CAPA);
3468 }
3469 if (mbk_LosigIsVSS(ptctc->SIG2)) coupledvsssig = 1;
3470 if (!coupledvsssig) { /* problem if SIG1 == vss_sig */
3471 ptctc->SIG2 = vss_sig;
3472 ptctc->NODE2 = vss_node;
3473 if (vss_sig->PRCN != NULL) {
3474 vss_sig->PRCN->PCTC = addchain (vss_sig->PRCN->PCTC, ptctc);
3475 }
3476 }
3477 else { /* ctc must be completely removed */
3478 if (ptctc->SIG1->PRCN != NULL) { /* list of ctc signals to update */
3479 for (ptchain1 = savechain; ptchain1; ptchain1 = ptchain1->NEXT) {
3480 if (ptchain1->DATA == ptctc->SIG1)
3481 break;
3482 }
3483 if (ptchain1 == NULL)
3484 savechain = addchain (savechain, ptctc->SIG1);
3485 }
3486 if (ptctc->SIG2->PRCN != NULL) { /* list of ctc signals to update */
3487 for (ptchain1 = savechain; ptchain1; ptchain1 = ptchain1->NEXT) {
3488 if (ptchain1->DATA == ptctc->SIG2)
3489 break;
3490 }
3491 if (ptchain1 == NULL)
3492 savechain = addchain (savechain, ptctc->SIG2);
3493 }
3494 ptctc->SIG1 = NULL;
3495 ptctc->SIG2 = NULL;
3496 ctctodelete = addchain (ctctodelete, ptctc);
3497 }
3498 }
3499 else {
3500 ptctc->SIG2 = (losig_list *) ptuser->DATA;
3501 }
3502 if (ptctc->SIG2 != NULL) {
3503 ptctc->SIG2->USER = addptype (ptctc->SIG2->USER, RCN_REPORTED, NULL);
3504 sigchain = addchain (sigchain, ptctc->SIG2);
3505 }
3506 }
3507 }
3508 }
3509 }
3510 for (ptchain = sigchain; ptchain; ptchain = ptchain->NEXT) {
3511 ptlosig = (losig_list *) ptchain->DATA;
3512 ptlosig->USER = delptype (ptlosig->USER, RCN_REPORTED);
3513 }
3514 freechain (sigchain);
3515 sigchain = NULL;
3516
3517 /* delete ctc references in signals */
3518 for (ptchain = savechain; ptchain; ptchain = ptchain->NEXT) {
3519 ptlosig = (losig_list *) ptchain->DATA;
3520 if (ptlosig->PRCN != NULL) {
3521 ptprevchain = NULL;
3522 for (ptchain1 = ptlosig->PRCN->PCTC; ptchain1; ptchain1 = ptnextchain) {
3523 ptnextchain = ptchain1->NEXT;
3524 ptctc = (loctc_list *) ptchain1->DATA;
3525 if (ptctc->SIG1 != ptlosig && ptctc->SIG2 != ptlosig) {
3526 if (ptprevchain != NULL)
3527 ptprevchain->NEXT = ptnextchain;
3528 else
3529 ptlosig->PRCN->PCTC = ptnextchain;
3530 ptchain1->NEXT = NULL;
3531 freechain (ptchain1);
3532 }
3533 else
3534 ptprevchain = ptchain1;
3535 }
3536 }
3537 }
3538 freechain (savechain);
3539
3540 /* delete unnecessary ctcs */
3541 for (ptchain = ctctodelete; ptchain; ptchain = ptchain->NEXT) {
3542 freeloctc ((loctc_list *) ptchain->DATA);
3543 }
3544 freechain (ctctodelete);
3545
3546 /* create terminals list */
3547 for (ptchain = lx_head; ptchain != NULL; ptchain = ptchain->NEXT) {
3548 intlocon = NULL;
3549 extlocon = NULL;
3550 translocon = NULL;
3551 foundterm = 0;
3552
3553 /* scan connectors list of the current signal */
3554 ptlosig = (losig_list *) (ptchain->DATA);
3555 if (ptlosig->PRCN != NULL) {
3556 loconnodes = NULL;
3557 toplevelnodes = NULL;
3558 countnode = 0;
3559 outconchain = NULL;
3560 nodetab = mbkalloc ((ptlosig->PRCN->NBNODE + 1) * sizeof (long));
3561 memset (nodetab, 0, (ptlosig->PRCN->NBNODE + 1) * sizeof (long));
3562 nodetab[0] = ptlosig->PRCN->NBNODE;
3563 }
3564
3565 loconchain = getptype (ptlosig->USER, LOFIGCHAIN)->DATA;
3566 for (; loconchain; loconchain = loconchain->NEXT) {
3567 ptlocon = (locon_list *) (loconchain->DATA);
3568 if (ptlocon->TYPE == 'T') {
3569 if (translocon == NULL) translocon = ptlocon;
3570 }
3571 else if (ptlocon->TYPE!='I' || (ptlocon->TYPE=='I' && getptype (((loins_list *) ptlocon->ROOT)->USER, UNFLATLOFIG) == NULL)) { /* external connector of new figure */
3572 if (ptlocon->TYPE == EXTERNAL) { /* external con. in root figure too */
3573 foundterm++;
3574 extlocon = ptlocon;
3575 }
3576 else if (extlocon == NULL)
3577 extlocon = ptlocon;
3578 if (ptlosig->PRCN != NULL) {
3579 for (ptnum = ptlocon->PNODE; ptnum; ptnum = ptnum->NEXT) {
3580 if (nodetab[ptnum->DATA] == 0) {
3581 countnode++;
3582 nodetab[ptnum->DATA] = countnode;
3583 }
3584 }
3585 outconchain = addchain (outconchain, ptlocon);
3586 }
3587 }
3588 else if (intlocon == NULL)
3589 intlocon = ptlocon; /* internal con. in new */
3590 } /* endfor loconchain */
3591
3592 /* build connector RC node lists */
3593 if (ptlosig->PRCN != NULL) {
3594 ptlosig->PRCN = NULL;
3595 addlorcnet (ptlosig);
3596 ptlosig->PRCN->NBNODE = countnode;
3597
3598 for (ptchain1 = outconchain; ptchain1; ptchain1 = ptchain1->NEXT) {
3599 ptlocon = (locon_list *) ptchain1->DATA;
3600 for (ptnum = ptlocon->PNODE; ptnum; ptnum = ptnum->NEXT) {
3601 ptnum->DATA = nodetab[ptnum->DATA];
3602 }
3603 }
3604 for (i = 1; i <= nodetab[0]; i++) {
3605 if (nodetab[i] != 0) {
3606 loconnodes = addnum (loconnodes, i);
3607 toplevelnodes = addnum (toplevelnodes, nodetab[i]);
3608 }
3609 }
3610 ptlosig->USER = addptype (ptlosig->USER, UNFLATRC, reverse ((chain_list *) toplevelnodes));
3611 mbkfree (nodetab);
3612 freechain (outconchain);
3613 }
3614
3615 /* create new external connector for the new figure */
3616 locondir = foundterm ? extlocon->DIRECTION : UNKNOWN;
3617 name = "unknown";
3618 if (foundterm)
3619 name = extlocon->NAME;
3620 else if (ptlosig->NAMECHAIN != NULL) {
3621 name = getsigname (ptlosig);
3622 }
3623 else if (intlocon) {
3624 name = intlocon->NAME;
3625 }
3626 strcpy (loconname, name);
3627
3628 newlosig = (losig_list *) getptype (ptlosig->USER, UNFLATLOFIG)->DATA;
3629 newlofig->LOCON = addlocon (newlofig, loconname, newlosig, locondir);
3630 if (ptlosig->PRCN != NULL) {
3631 loconnodes = (num_list *) reverse ((chain_list *) loconnodes);
3632 newlofig->LOCON->PNODE = loconnodes;
3633 }
3634 }
3635
3636 /* create instances list */
3637 for (ptchain = list; ptchain != NULL; ptchain = ptchain->NEXT) {
3638 ptloins = (loins_list *)ptchain->DATA;
3639 newloins = rduploins(ptloins);
3640 newloins->NEXT = newlofig->LOINS;
3641 newlofig->LOINS = newloins;
3642 for (newlocon = newloins->LOCON, ptlocon = ptloins->LOCON; newlocon != NULL && ptlocon != NULL; newlocon = newlocon->NEXT, ptlocon = ptlocon->NEXT) {
3643 newlocon->SIG = (losig_list *)getptype(ptlocon->SIG->USER, UNFLATLOFIG)->DATA;
3644 }
3645 }
3646
3647 /* create transistor list */
3648 for (ptlotrs = ptfig->LOTRS; ptlotrs; ptlotrs = ptlotrs->NEXT) {
3649 ptsource = (losig_list *)getptype(ptlotrs->SOURCE->SIG->USER, UNFLATLOFIG)->DATA;
3650 ptdrain = (losig_list *)getptype(ptlotrs->DRAIN->SIG->USER, UNFLATLOFIG)->DATA;
3651 ptgrid = (losig_list *)getptype(ptlotrs->GRID->SIG->USER, UNFLATLOFIG)->DATA;
3652 if (ptlotrs->BULK) ptbulk = (losig_list *)getptype(ptlotrs->BULK->SIG->USER, UNFLATLOFIG)->DATA;
3653 newlotrs = rduplotrs(ptlotrs);
3654 newlotrs->NEXT = newlofig->LOTRS;
3655 newlofig->LOTRS = newlotrs;
3656 newlotrs->SOURCE->SIG = ptsource;
3657 newlotrs->DRAIN->SIG = ptdrain;
3658 newlotrs->GRID->SIG = ptgrid;
3659 if (ptlotrs->BULK) newlotrs->BULK->SIG = ptbulk;
3660 }
3661 newlofig->LOTRS = (lotrs_list *)reverse((chain_list *)newlofig->LOTRS);
3662
3663 /***** free ptype lists (unflatlofig) */
3664 /* free unflatlofig in lx signals */
3665 for (ptchain = lx_head; ptchain != NULL; ptchain = ptchain->NEXT) {
3666 ptlosig = (losig_list *)ptchain->DATA;
3667 ptlosig->USER = delptype(ptlosig->USER, UNFLATLOFIG);
3668 }
3669
3670 /* free unflatlofig in li signals */
3671 for (ptchain = li_head; ptchain != NULL; ptchain = ptchain->NEXT) {
3672 ptlosig = (losig_list *)ptchain->DATA;
3673 ptlosig->USER = delptype(ptlosig->USER, UNFLATLOFIG);
3674 }
3675
3676 /* free unflatlofig in list instances */
3677 for (ptchain = list; ptchain != NULL; ptchain = ptchain->NEXT) {
3678 ptloins = (loins_list *)ptchain->DATA;
3679 ptloins->USER = delptype(ptloins->USER, UNFLATLOFIG);
3680 }
3681
3682 /***** modify the root figure :*/
3683 /* add new instantiated figure */
3684 lx_head = reverse(lx_head);
3685 ptfig->LOINS = addloins(ptfig, insname, getlofig (figname, 'P'), lx_head);
3686 for (ptlocon = ptfig->LOINS->LOCON; ptlocon; ptlocon = ptlocon->NEXT) {
3687 if ((ptuser = getptype (ptlocon->SIG->USER, UNFLATRC)) != NULL) {
3688 ptlocon->PNODE = (num_list *)ptuser->DATA;
3689 }
3690 }
3691
3692 /* delete signals */
3693 for (ptchain = li_head; ptchain != NULL; ptchain = ptchain->NEXT) {
3694 ptlosig = (losig_list *)ptchain->DATA;
3695 freechain (ptlosig->NAMECHAIN);
3696 ptlosig->NAMECHAIN = NULL;
3697 }
3698 ptprevsig = NULL;
3699 for (ptlosig = ptfig->LOSIG; ptlosig; ptlosig = ptnextsig) {
3700 ptnextsig = ptlosig->NEXT;
3701 if (ptlosig->NAMECHAIN == NULL) {
3702 if (ptprevsig != NULL)
3703 ptprevsig->NEXT = ptnextsig;
3704 else
3705 ptfig->LOSIG = ptnextsig;
3706 ptlosig->INDEX = 0L;
3707 dellosiguser (ptlosig);
3708 }
3709 else
3710 ptprevsig = ptlosig;
3711 }
3712 freechain (li_head);
3713 freechain (lx_head);
3714
3715 delete_flag = namealloc("mbk_delete_flag");
3716
3717 /* delete instances */
3718 for (ptchain = list; ptchain != NULL; ptchain = ptchain->NEXT) {
3719 ptloins = (loins_list *) ptchain->DATA;
3720 ptloins->INSNAME = NULL;
3721 }
3722 delflaggedloins(ptfig);
3723
3724 /* update modelchain */
3725 freechain (ptfig->MODELCHAIN);
3726 ptfig->MODELCHAIN = NULL;
3727 for (ptloins = ptfig->LOINS; ptloins; ptloins = ptloins->NEXT) {
3728 name = ptloins->FIGNAME;
3729 for (ptchain = ptfig->MODELCHAIN; ptchain; ptchain = ptchain->NEXT) {
3730 if (ptchain->DATA == name)
3731 break;
3732 }
3733 if (ptchain == NULL) {
3734 ptfig->MODELCHAIN = addchain (ptfig->MODELCHAIN, name);
3735 }
3736 }
3737
3738 /* delete transistors */
3739 for (ptlotrs = ptfig->LOTRS; ptlotrs; ptlotrs = ptlotrs->NEXT) ptlotrs->TRNAME = delete_flag;
3740 delflaggedlotrs(ptfig, delete_flag);
3741
3742 /* free lofigchain */
3743 for (ptlosig = ptfig->LOSIG; ptlosig != NULL; ptlosig = ptlosig->NEXT) {
3744 ptuser = getptype (ptlosig->USER, (long)LOFIGCHAIN);
3745 if (ptuser) {
3746 freechain ((chain_list *) ptuser->DATA);
3747 ptlosig->USER = delptype (ptlosig->USER, LOFIGCHAIN);
3748 }
3749 }
3750
3751 return newlofig;
3752 }
3753
3754 #define OK 1
3755 #define PROBLEM 0
3756 #define NOVBE -1
3757
3758
3759
3760 struct typoin { /* structure used by dast_dbg *//* to store its state */
3761 short type; /* code of the current structure */
3762 short mark; /* stop mark */
3763 void *data; /* pointer of the structure */
3764 };
3765
3766 #define VHD_ERRDFN -1
3767 #define VHD__XTDFN 0
3768 #define VHD__UPDFN 1
3769 #define VHD__TPDFN 2
3770 #define VHD__SPDFN 3
3771 #define VHD__BKDFN 4
3772
3773 #define VHD_lofigDFN 5
3774 #define VHD_nextDFN 6
3775 #define VHD_modelchainDFN 7
3776 #define VHD_loconDFN 8
3777 #define VHD_losigDFN 9
3778 #define VHD_bksigDFN 10
3779 #define VHD_loinsDFN 11
3780 #define VHD_lotrsDFN 13
3781 #define VHD_nameDFN 14
3782 #define VHD_modeDFN 15
3783 #define VHD_userDFN 16
3784 #define VHD_drainDFN 17
3785 #define VHD_gridDFN 18
3786 #define VHD_sourceDFN 19
3787 #define VHD_bulkDFN 36
3788 #define VHD_widthDFN 20
3789 #define VHD_lengthDFN 21
3790 #define VHD_xDFN 22
3791 #define VHD_yDFN 23
3792 #define VHD_typeDFN 24
3793 #define VHD_insnameDFN 25
3794 #define VHD_fignameDFN 26
3795 #define VHD_sigDFN 27
3796 #define VHD_rootDFN 28
3797 #define VHD_directionDFN 29
3798 #define VHD_valDFN 30
3799 #define VHD_namechainDFN 31
3800 #define VHD_capaDFN 32
3801 #define VHD_indexDFN 33
3802 #define VHD_ptypeDFN 34
3803 #define VHD_dataDFN 35
3804
3805 #define VHD_MAXDFN 37
3806 static int vhd_getcmd ();
3807 static int vhd_hash ();
3808
3809 void mlodebug (head_pnt, stru_name)
3810
3811 void *head_pnt;
3812 char *stru_name;
3813
3814 {
3815
3816 int i;
3817 int state;
3818 int newsta0;
3819 int readcmd = 0;
3820 char readtab[3][20];
3821 int stk_pnt = 0;
3822 int type = VHD__XTDFN;
3823 struct chain *ptchain;
3824
3825 struct typoin current_pnt;
3826 struct typoin stk[200];
3827
3828 char empty[4];
3829 char avail[12];
3830
3831 int key[VHD_MAXDFN];
3832 char *tab[VHD_MAXDFN];
3833 void *nxt[VHD_MAXDFN];
3834 short typ[VHD_MAXDFN];
3835
3836 struct lofig *lofig_pnt;
3837 struct locon *locon_pnt;
3838 struct losig *losig_pnt;
3839 ptype_list *ptype_pnt;
3840 struct loins *loins_pnt;
3841 struct lotrs *lotrs_pnt;
3842
3843 key[VHD_lofigDFN] = vhd_hash ("lofig");
3844 key[VHD_nextDFN] = vhd_hash ("next");
3845 key[VHD_modelchainDFN] = vhd_hash ("modelchain");
3846 key[VHD_loconDFN] = vhd_hash ("locon");
3847 key[VHD_losigDFN] = vhd_hash ("losig");
3848 key[VHD_bksigDFN] = vhd_hash ("bksig");
3849 key[VHD_loinsDFN] = vhd_hash ("loins");
3850 key[VHD_lotrsDFN] = vhd_hash ("lotrs");
3851 key[VHD_nameDFN] = vhd_hash ("name");
3852 key[VHD_modeDFN] = vhd_hash ("mode");
3853 key[VHD_userDFN] = vhd_hash ("user");
3854 key[VHD_drainDFN] = vhd_hash ("drain");
3855 key[VHD_gridDFN] = vhd_hash ("grid");
3856 key[VHD_sourceDFN] = vhd_hash ("source");
3857 key[VHD_bulkDFN] = vhd_hash ("bulk");
3858 key[VHD_widthDFN] = vhd_hash ("width");
3859 key[VHD_lengthDFN] = vhd_hash ("length");
3860 key[VHD_xDFN] = vhd_hash ("x");
3861 key[VHD_yDFN] = vhd_hash ("y");
3862 key[VHD_typeDFN] = vhd_hash ("type");
3863 key[VHD_insnameDFN] = vhd_hash ("insname");
3864 key[VHD_fignameDFN] = vhd_hash ("figname");
3865 key[VHD_sigDFN] = vhd_hash ("sig");
3866 key[VHD_rootDFN] = vhd_hash ("root");
3867 key[VHD_directionDFN] = vhd_hash ("direction");
3868 key[VHD_valDFN] = vhd_hash ("val");
3869 key[VHD_namechainDFN] = vhd_hash ("namechain");
3870 key[VHD_capaDFN] = vhd_hash ("capa");
3871 key[VHD_indexDFN] = vhd_hash ("index");
3872 key[VHD_ptypeDFN] = vhd_hash ("ptype");
3873
3874 /* ###------------------------------------------------------### */
3875 /* Set of predefined commands */
3876 /* ###------------------------------------------------------### */
3877
3878 key[0] = vhd_hash ("_exit");
3879 key[1] = vhd_hash ("_up");
3880 key[2] = vhd_hash ("_top");
3881 key[3] = vhd_hash ("_stop");
3882 key[4] = vhd_hash ("_back");
3883
3884 (void)strcpy (empty, "");
3885 (void)strcpy (avail, "AVAILABLE");
3886
3887 for (i = 0; i < VHD_MAXDFN; i++)
3888 typ[i] = i;
3889
3890 /* ###------------------------------------------------------### */
3891 /* Find the type of the head structure */
3892 /* ###------------------------------------------------------### */
3893
3894 readcmd = vhd_hash (stru_name);
3895 for (i = 0; i < VHD_MAXDFN; i++) {
3896 if (readcmd == key[i]) {
3897 type = typ[i];
3898 break;
3899 }
3900 }
3901
3902 /* ###------------------------------------------------------### */
3903 /* Exit if the head structure is empty */
3904 /* ###------------------------------------------------------### */
3905
3906 if (head_pnt == NULL)
3907 type = VHD__XTDFN;
3908
3909 current_pnt.data = head_pnt;
3910 current_pnt.type = type;
3911
3912 state = type;
3913
3914 while (state != VHD__XTDFN) {
3915 /* ###------------------------------------------------------### */
3916 /* Print structure's field until the exit command is read */
3917 /* ###------------------------------------------------------### */
3918
3919 for (i = 0; i < VHD_MAXDFN; i++) {
3920 tab[i] = empty;
3921 nxt[i] = NULL;
3922 }
3923
3924 /* ###------------------------------------------------------### */
3925 /* _exit and _stop commands are allways available */
3926 /* ###------------------------------------------------------### */
3927
3928 tab[VHD__XTDFN] = avail;
3929 tab[VHD__SPDFN] = avail;
3930
3931 /* ###------------------------------------------------------### */
3932 /* _up, _top, and _back commands are available only if the */
3933 /* stack is not empty */
3934 /* ###------------------------------------------------------### */
3935
3936 if (stk_pnt != 0) {
3937 tab[VHD__UPDFN] = avail;
3938 tab[VHD__TPDFN] = avail;
3939 tab[VHD__BKDFN] = avail;
3940 }
3941
3942 switch (state) {
3943
3944 case (VHD_lofigDFN):
3945
3946 /* ###--------- lofig ---------### */
3947
3948 lofig_pnt = (struct lofig *)(current_pnt.data);
3949
3950 if (lofig_pnt->NEXT != NULL) {
3951 tab[VHD_nextDFN] = avail;
3952 nxt[VHD_nextDFN] = (void *)lofig_pnt->NEXT;
3953 typ[VHD_nextDFN] = VHD_lofigDFN;
3954 }
3955 if (lofig_pnt->LOCON != NULL) {
3956 tab[VHD_loconDFN] = avail;
3957 nxt[VHD_loconDFN] = (void *)lofig_pnt->LOCON;
3958 typ[VHD_loconDFN] = VHD_loconDFN;
3959 }
3960 if (lofig_pnt->LOSIG != NULL) {
3961 tab[VHD_losigDFN] = avail;
3962 nxt[VHD_losigDFN] = (void *)lofig_pnt->LOSIG;
3963 typ[VHD_losigDFN] = VHD_losigDFN;
3964 }
3965 if (lofig_pnt->BKSIG.TAB != NULL) {
3966 tab[VHD_bksigDFN] = avail;
3967 nxt[VHD_bksigDFN] = (void *)lofig_pnt->BKSIG.TAB;
3968 typ[VHD_bksigDFN] = VHD_ptypeDFN;
3969 }
3970 if (lofig_pnt->LOINS != NULL) {
3971 tab[VHD_loinsDFN] = avail;
3972 nxt[VHD_loinsDFN] = (void *)lofig_pnt->LOINS;
3973 typ[VHD_loinsDFN] = VHD_loinsDFN;
3974 }
3975 if (lofig_pnt->LOTRS != NULL) {
3976 tab[VHD_lotrsDFN] = avail;
3977 nxt[VHD_lotrsDFN] = (void *)lofig_pnt->LOTRS;
3978 typ[VHD_lotrsDFN] = VHD_lotrsDFN;
3979 }
3980 if (lofig_pnt->USER != NULL) {
3981 tab[VHD_userDFN] = avail;
3982 nxt[VHD_userDFN] = (void *)lofig_pnt->USER;
3983 typ[VHD_userDFN] = VHD_ptypeDFN;
3984 }
3985
3986 ptchain = lofig_pnt->MODELCHAIN;
3987 (void)printf (" modelchain :\n");
3988 while (ptchain != NULL) {
3989 (void)printf (" %s\n", (char *)ptchain->DATA);
3990 ptchain = ptchain->NEXT;
3991 }
3992
3993 (void)printf (" name : %s\n", lofig_pnt->NAME);
3994 (void)printf (" mode : %c\n", lofig_pnt->MODE);
3995 (void)printf ("-> locon : %s\n", tab[VHD_loconDFN]);
3996 (void)printf ("-> losig : %s\n", tab[VHD_losigDFN]);
3997 (void)printf ("-> bksig : %s\n", tab[VHD_bksigDFN]);
3998 (void)printf ("-> loins : %s\n", tab[VHD_loinsDFN]);
3999 (void)printf ("-> lotrs : %s\n", tab[VHD_lotrsDFN]);
4000 (void)printf ("-> user : %s\n", tab[VHD_userDFN]);
4001 (void)printf ("-> next : %s\n", tab[VHD_nextDFN]);
4002
4003 break;
4004
4005 case (VHD_lotrsDFN):
4006
4007 /* ###--------- lotrs ---------### */
4008
4009 lotrs_pnt = (struct lotrs *)(current_pnt.data);
4010
4011 if (lotrs_pnt->NEXT != NULL) {
4012 tab[VHD_nextDFN] = avail;
4013 nxt[VHD_nextDFN] = (void *)lotrs_pnt->NEXT;
4014 typ[VHD_nextDFN] = VHD_lotrsDFN;
4015 }
4016 if (lotrs_pnt->DRAIN != NULL) {
4017 tab[VHD_drainDFN] = avail;
4018 nxt[VHD_drainDFN] = (void *)lotrs_pnt->DRAIN;
4019 typ[VHD_drainDFN] = VHD_loconDFN;
4020 }
4021 if (lotrs_pnt->GRID != NULL) {
4022 tab[VHD_gridDFN] = avail;
4023 nxt[VHD_gridDFN] = (void *)lotrs_pnt->GRID;
4024 typ[VHD_gridDFN] = VHD_loconDFN;
4025 }
4026 if (lotrs_pnt->SOURCE != NULL) {
4027 tab[VHD_sourceDFN] = avail;
4028 nxt[VHD_sourceDFN] = (void *)lotrs_pnt->SOURCE;
4029 typ[VHD_sourceDFN] = VHD_loconDFN;
4030 }
4031 if (lotrs_pnt->BULK != NULL) {
4032 tab[VHD_sourceDFN] = avail;
4033 nxt[VHD_sourceDFN] = (void *)lotrs_pnt->BULK;
4034 typ[VHD_sourceDFN] = VHD_loconDFN;
4035 }
4036 if (lotrs_pnt->USER != NULL) {
4037 tab[VHD_userDFN] = avail;
4038 nxt[VHD_userDFN] = (void *)lotrs_pnt->USER;
4039 typ[VHD_userDFN] = VHD_ptypeDFN;
4040 }
4041
4042 (void)printf ("-> drain : %s\n", tab[VHD_drainDFN]);
4043 (void)printf ("-> grid : %s\n", tab[VHD_gridDFN]);
4044 (void)printf ("-> source : %s\n", tab[VHD_sourceDFN]);
4045 (void)printf ("-> bulk : %s\n", tab[VHD_bulkDFN]);
4046 (void)printf (" length : %ld\n", lotrs_pnt->LENGTH);
4047 (void)printf (" width : %ld\n", lotrs_pnt->WIDTH);
4048 (void)printf (" y : %ld\n", lotrs_pnt->Y);
4049 (void)printf (" x : %ld\n", lotrs_pnt->X);
4050 (void)printf (" type : %c\n", lotrs_pnt->TYPE);
4051 (void)printf ("-> user : %s\n", tab[VHD_userDFN]);
4052 (void)printf ("-> next : %s\n", tab[VHD_nextDFN]);
4053
4054 break;
4055
4056 case (VHD_loinsDFN):
4057
4058 /* ###--------- loins ---------### */
4059
4060 loins_pnt = (struct loins *)(current_pnt.data);
4061
4062 if (loins_pnt->NEXT != NULL) {
4063 tab[VHD_nextDFN] = avail;
4064 nxt[VHD_nextDFN] = (void *)loins_pnt->NEXT;
4065 typ[VHD_nextDFN] = VHD_loinsDFN;
4066 }
4067 if (loins_pnt->LOCON != NULL) {
4068 tab[VHD_loconDFN] = avail;
4069 nxt[VHD_loconDFN] = (void *)loins_pnt->LOCON;
4070 typ[VHD_loconDFN] = VHD_loconDFN;
4071 }
4072 if (loins_pnt->USER != NULL) {
4073 tab[VHD_userDFN] = avail;
4074 nxt[VHD_userDFN] = (void *)loins_pnt->USER;
4075 typ[VHD_userDFN] = VHD_ptypeDFN;
4076 }
4077
4078 (void)printf (" insname : %s\n", loins_pnt->INSNAME);
4079 (void)printf (" figname : %s\n", loins_pnt->FIGNAME);
4080 (void)printf ("-> locon : %s\n", tab[VHD_loconDFN]);
4081 (void)printf ("-> user : %s\n", tab[VHD_userDFN]);
4082 (void)printf ("-> next : %s\n", tab[VHD_nextDFN]);
4083
4084 break;
4085
4086 case (VHD_loconDFN):
4087
4088 /* ###--------- locon ---------### */
4089
4090 locon_pnt = (struct locon *)(current_pnt.data);
4091
4092 if (locon_pnt->NEXT != NULL) {
4093 tab[VHD_nextDFN] = avail;
4094 nxt[VHD_nextDFN] = (void *)locon_pnt->NEXT;
4095 typ[VHD_nextDFN] = VHD_loconDFN;
4096 }
4097 if (locon_pnt->SIG != NULL) {
4098 tab[VHD_sigDFN] = avail;
4099 nxt[VHD_sigDFN] = (void *)locon_pnt->SIG;
4100 typ[VHD_sigDFN] = VHD_losigDFN;
4101 }
4102 if (locon_pnt->ROOT != NULL) {
4103 tab[VHD_rootDFN] = avail;
4104 nxt[VHD_rootDFN] = (void *)locon_pnt->ROOT;
4105 if (locon_pnt->TYPE == 'I')
4106 typ[VHD_rootDFN] = VHD_loinsDFN;
4107 else
4108 typ[VHD_rootDFN] = VHD_lofigDFN;
4109 }
4110 if (locon_pnt->USER != NULL) {
4111 tab[VHD_userDFN] = avail;
4112 nxt[VHD_userDFN] = (void *)locon_pnt->USER;
4113 typ[VHD_userDFN] = VHD_ptypeDFN;
4114 }
4115
4116 (void)printf (" name : %s\n", locon_pnt->NAME);
4117 (void)printf ("-> sig : %s\n", tab[VHD_sigDFN]);
4118 (void)printf ("-> root : %s\n", tab[VHD_rootDFN]);
4119 (void)printf (" direction : %c\n", locon_pnt->DIRECTION);
4120 (void)printf (" type : %c\n", locon_pnt->TYPE);
4121 (void)printf ("-> user : %s\n", tab[VHD_userDFN]);
4122 (void)printf ("-> next : %s\n", tab[VHD_nextDFN]);
4123
4124 break;
4125
4126 case (VHD_losigDFN):
4127
4128 /* ###--------- losig ---------### */
4129
4130 losig_pnt = (struct losig *)(current_pnt.data);
4131
4132 if (losig_pnt->NEXT != NULL) {
4133 tab[VHD_nextDFN] = avail;
4134 nxt[VHD_nextDFN] = (void *)losig_pnt->NEXT;
4135 typ[VHD_nextDFN] = VHD_losigDFN;
4136 }
4137 if (losig_pnt->USER != NULL) {
4138 tab[VHD_userDFN] = avail;
4139 nxt[VHD_userDFN] = (void *)losig_pnt->USER;
4140 typ[VHD_userDFN] = VHD_ptypeDFN;
4141 }
4142
4143 ptchain = losig_pnt->NAMECHAIN;
4144 (void)printf (" namechain :\n");
4145 while (ptchain != NULL) {
4146 (void)printf (" %s\n", (char *)ptchain->DATA);
4147 ptchain = ptchain->NEXT;
4148 }
4149
4150 (void)printf (" capa : %f\n", rcn_getcapa (NULL, losig_pnt));
4151 (void)printf (" index : %ld\n", losig_pnt->INDEX);
4152 (void)printf (" type : %c\n", losig_pnt->TYPE);
4153 (void)printf ("-> user : %s\n", tab[VHD_userDFN]);
4154 (void)printf ("-> next : %s\n", tab[VHD_nextDFN]);
4155
4156 break;
4157
4158 case (VHD_ptypeDFN):
4159
4160 /* ###--------- ptype ---------### */
4161
4162 ptype_pnt = (ptype_list *) (current_pnt.data);
4163
4164 if (ptype_pnt->NEXT != NULL) {
4165 tab[VHD_nextDFN] = avail;
4166 nxt[VHD_nextDFN] = (void *)ptype_pnt->NEXT;
4167 typ[VHD_nextDFN] = VHD_ptypeDFN;
4168 }
4169 if (ptype_pnt->DATA != NULL) {
4170 tab[VHD_dataDFN] = avail;
4171 nxt[VHD_dataDFN] = (void *)ptype_pnt->DATA;
4172 typ[VHD_dataDFN] = VHD_ERRDFN;
4173 /*......typ[VHD_dataDFN] = .......................*/
4174 }
4175
4176 (void)printf (" type : %ld\n", ptype_pnt->TYPE);
4177 (void)printf ("-> data : %s\n", tab[VHD_dataDFN]);
4178 (void)printf ("-> next : %s\n", tab[VHD_nextDFN]);
4179
4180 break;
4181
4182
4183 }
4184
4185 /* ###------------------------------------------------------### */
4186 /* Reading new command */
4187 /* ###------------------------------------------------------### */
4188
4189 readcmd = vhd_getcmd (readtab);
4190
4191 for (i = 0; i < VHD_MAXDFN; i++) {
4192 if (readcmd == key[i])
4193 break;
4194 }
4195 if ((i != VHD_MAXDFN + 1) && (tab[i] == avail))
4196 newsta0 = i;
4197 else
4198 newsta0 = -1;
4199
4200 /* ###------------------------------------------------------### */
4201 /* Analysing new command */
4202 /* ###------------------------------------------------------### */
4203
4204 switch (newsta0) {
4205 case (VHD__UPDFN):
4206 current_pnt = stk[--stk_pnt];
4207 break;
4208
4209 case (VHD__BKDFN):
4210 while ((--stk_pnt != 0) && (stk[stk_pnt].mark != 1));
4211 current_pnt = stk[stk_pnt];
4212 break;
4213
4214 case (VHD__SPDFN):
4215 current_pnt.mark = 1;
4216 break;
4217
4218 case (VHD__TPDFN):
4219 current_pnt = stk[0];
4220 stk_pnt = 0;
4221 break;
4222
4223 case (VHD__XTDFN):
4224 current_pnt.data = NULL;
4225 current_pnt.type = VHD__XTDFN;
4226 current_pnt.mark = 0;
4227 break;
4228
4229 case (VHD_ERRDFN):
4230 break;
4231
4232 default:
4233 stk[stk_pnt++] = current_pnt;
4234 current_pnt.type = typ[newsta0];
4235 current_pnt.mark = 0;
4236 current_pnt.data = nxt[newsta0];
4237 break;
4238
4239 }
4240
4241 state = current_pnt.type;
4242 }
4243 }
4244
4245
4246 static int vhd_getcmd (prvcmd)
4247
4248 char prvcmd[3][20];
4249
4250 {
4251 char readstr[60];
4252 char comd0[20];
4253 char comd1[20];
4254 char comd2[20];
4255 int code;
4256
4257 (void)printf ("\n\n\n COMMAND >> ");
4258 comd0[0] = '\0';
4259 comd1[0] = '\0';
4260 comd2[0] = '\0';
4261 (void)fgets (readstr, 60, stdin);
4262 (void)sscanf (readstr, "%s%s%s", comd0, comd1, comd2);
4263
4264 if (strcmp (comd0, ".")) {
4265 (void)strcpy (prvcmd[0], comd0);
4266 (void)strcpy (prvcmd[1], comd1);
4267 (void)strcpy (prvcmd[2], comd2);
4268 }
4269 code = vhd_hash (prvcmd[0]);
4270
4271 (void)printf ("\n\n\n\n\n");
4272 return (code);
4273 }
4274
4275
4276
4277 static int vhd_hash (str)
4278
4279 char *str;
4280
4281 {
4282 int code = 0;
4283
4284 while (*str != '\0')
4285 code = code << 1 ^ *str++;
4286
4287 return (code);
4288 }
4289
4290 optparam_list *dupoptparamlst (optparam_ptr)
4291 optparam_list *optparam_ptr;
4292 {
4293 optparam_list *optparam_rpt = NULL; /* Returned locon pointer */
4294 optparam_list *optparam_tmpptr = NULL; /* Temporary pointer */
4295
4296 while (optparam_ptr != NULL) {
4297 optparam_tmpptr = dupoptparam (optparam_ptr);
4298 optparam_tmpptr->NEXT = optparam_rpt;
4299 optparam_rpt = optparam_tmpptr;
4300
4301 optparam_ptr = optparam_ptr->NEXT;
4302 }
4303 optparam_rpt = (optparam_list *) reverse ((chain_list *) optparam_rpt);
4304 return (optparam_rpt);
4305 }
4306
4307 optparam_list *dupoptparam (optparam_ptr)
4308 optparam_list *optparam_ptr;
4309 {
4310 optparam_list *optparam_rpt = NULL; /* Returned optparam pointer */
4311 // eqt_ctx dummy;
4312 static eqt_ctx *dummy=NULL;
4313 if (optparam_ptr == NULL)
4314 return NULL;
4315
4316 optparam_rpt = (optparam_list *) (mbkalloc (sizeof (optparam_list)));
4317 *optparam_rpt = *optparam_ptr;
4318 if (optparam_ptr->TAG=='$')
4319 {
4320 if (optparam_rpt->EQT_EXPR==NULL)
4321 {
4322 if (dummy==NULL) dummy=spi_init_eqt ();
4323 // optparam_ptr->EQT_EXPR=optparam_rpt->EQT_EXPR=eqt_create (&dummy, optparam_ptr->UDATA.EXPR);
4324 optparam_ptr->EQT_EXPR=optparam_rpt->EQT_EXPR=eqt_create (dummy, optparam_ptr->UDATA.EXPR);
4325 if (optparam_rpt->EQT_EXPR!=NULL) ((eqt_node *)optparam_rpt->EQT_EXPR)->REF_COUNT=2;
4326 // eqt_term (dummy);
4327 }
4328 else
4329 ((eqt_node *)optparam_rpt->EQT_EXPR)->REF_COUNT++;
4330 }
4331 optparam_rpt->NEXT = NULL;
4332
4333 return (optparam_rpt);
4334 }
4335
4336 /*##------------------------------------------------------------------##*/
4337 /* Author : VUONG H.N. */
4338 /* Date : Dec 11 1991 */
4339 /* Cont. : Essentially functions to duplicate lofig structures */
4340 /* such a complete LOFIG or just a chain_list. */
4341 /*##------------------------------------------------------------------##*/
4342
4343 /*##------------------------------------------------------------------##*/
4344 /* Function : duploconlst() */
4345 /* contents : duplicate a locon list and return a pointer on the new */
4346 /* structure. */
4347 /* called func. : duplocon(), reverse(), */
4348 /*##------------------------------------------------------------------##*/
4349
4350 locon_list *duploconlst (locon_ptr)
4351 locon_list *locon_ptr;
4352 {
4353 locon_list *locon_rpt = NULL; /* Returned locon pointer */
4354 locon_list *locon_tmpptr = NULL; /* Temporary pointer */
4355
4356 while (locon_ptr != NULL) {
4357 locon_tmpptr = duplocon (locon_ptr);
4358 locon_tmpptr->NEXT = locon_rpt;
4359 locon_rpt = locon_tmpptr;
4360
4361 locon_ptr = locon_ptr->NEXT;
4362 }
4363 locon_rpt = (locon_list *) reverse ((chain_list *) locon_rpt);
4364 return (locon_rpt);
4365 }
4366
4367 /*##------------------------------------------------------------------##*/
4368 /* Function : duplocon() */
4369 /* contents : duplicate a locon and return a pointer on the new */
4370 /* structure. */
4371 /* called func. : mbkalloc(), */
4372 /* note : the ROOT and the SIG pointer are also duplicated */
4373 /*##------------------------------------------------------------------##*/
4374
4375 locon_list *duplocon (locon_ptr)
4376 locon_list *locon_ptr;
4377 {
4378 locon_list *locon_rpt = NULL; /* Returned locon pointer */
4379 num_list *sn;
4380 ptype_list *ptnodename;
4381
4382 if (locon_ptr == NULL)
4383 return NULL;
4384
4385 locon_rpt = (locon_list *) (mbkalloc (sizeof (locon_list)));
4386 locon_rpt->NEXT = NULL;
4387 locon_rpt->NAME = locon_ptr->NAME;
4388 locon_rpt->SIG = locon_ptr->SIG;
4389 locon_rpt->ROOT = locon_ptr->ROOT;
4390 locon_rpt->DIRECTION = locon_ptr->DIRECTION;
4391 locon_rpt->TYPE = locon_ptr->TYPE;
4392
4393 locon_rpt->PNODE = NULL;
4394 for (sn = locon_ptr->PNODE; sn; sn = sn->NEXT)
4395 locon_rpt->PNODE = addnum (locon_rpt->PNODE, sn->DATA);
4396 locon_rpt->PNODE = (num_list *) reverse ((chain_list *) locon_rpt->PNODE);
4397
4398 locon_rpt->USER = NULL; /* The ptype_list is not duplicated */
4399
4400 if ((ptnodename = getptype (locon_ptr->USER, PNODENAME)))
4401 locon_rpt->USER = addptype (locon_rpt->USER, PNODENAME, dupchainlst (ptnodename->DATA)
4402 );
4403 if ((ptnodename = getptype (locon_ptr->USER, LOCON_INFORMATION)))
4404 locon_rpt->USER = addptype (locon_rpt->USER, LOCON_INFORMATION, ptnodename->DATA);
4405
4406 return (locon_rpt);
4407 }
4408
4409 /*##------------------------------------------------------------------##*/
4410 /* Function : duploinslst() */
4411 /* contents : duplicate a loins list and return a pointer on the new */
4412 /* structure. */
4413 /* called func. : duploins(), reverse(), */
4414 /*##------------------------------------------------------------------##*/
4415
4416 loins_list *duploinslst (loins_ptr)
4417 loins_list *loins_ptr;
4418 {
4419 loins_list *loins_rpt = NULL; /* Returned loins pointer */
4420 loins_list *loins_tmpptr = NULL; /* Temporary pointer */
4421
4422 while (loins_ptr != NULL) {
4423 loins_tmpptr = duploins (loins_ptr);
4424 loins_tmpptr->NEXT = loins_rpt;
4425 loins_rpt = loins_tmpptr;
4426
4427 loins_ptr = loins_ptr->NEXT;
4428 }
4429 loins_rpt = (loins_list *) reverse ((chain_list *) loins_rpt);
4430 return (loins_rpt);
4431 }
4432
4433 /*##------------------------------------------------------------------##*/
4434 /* Function : duploins() */
4435 /* contents : duplicate a loins and return a pointer on the new */
4436 /* structure. */
4437 /* called func. : mbkalloc(), */
4438 /* note : the LOCON pointer is also duplicated */
4439 /*##------------------------------------------------------------------##*/
4440
4441 loins_list *duploins (loins_ptr)
4442 loins_list *loins_ptr;
4443 {
4444 loins_list *loins_rpt = NULL; /* Returned loins pointer */
4445 ptype_list *ptuser;
4446 xy_struct *xy;
4447
4448 loins_rpt = (loins_list *) (mbkalloc (sizeof (loins_list)));
4449 loins_rpt->NEXT = NULL;
4450 loins_rpt->LOCON = loins_ptr->LOCON;
4451 loins_rpt->INSNAME = loins_ptr->INSNAME;
4452 loins_rpt->FIGNAME = loins_ptr->FIGNAME;
4453 loins_rpt->USER = NULL; /* The ptype_list is not duplicated */
4454
4455 if ((ptuser = getptype (loins_ptr->USER, OPT_PARAMS)) != NULL) {
4456 loins_rpt->USER = addptype (loins_rpt->USER, OPT_PARAMS, dupoptparamlst ((optparam_list *) ptuser->DATA));
4457 }
4458
4459 if ((ptuser = getptype (loins_ptr->USER, MSL_XY_PTYPE)) != NULL) {
4460 xy = mbkalloc (sizeof (struct xy_struct));
4461 xy->X = ((xy_struct*)ptuser->DATA)->X;
4462 xy->Y = ((xy_struct*)ptuser->DATA)->Y;
4463 xy->A = xy->R = xy->Tx = xy->Ty = 0;
4464 loins_rpt->USER = addptype (loins_rpt->USER, MSL_XY_PTYPE, xy);
4465 }
4466
4467 return (loins_rpt);
4468 }
4469
4470 /*##------------------------------------------------------------------##*/
4471 /* Function : duplotrslst() */
4472 /* contents : duplicate a lotrs list and return a pointer on the new */
4473 /* structure. */
4474 /* called func. : duplotrs(), reverse(), */
4475 /*##------------------------------------------------------------------##*/
4476
4477 lotrs_list *duplotrslst (lotrs_ptr)
4478 lotrs_list *lotrs_ptr;
4479 {
4480 lotrs_list *lotrs_rpt = NULL; /* Returned lotrs pointer */
4481 lotrs_list *lotrs_tmpptr = NULL; /* Temporary pointer */
4482
4483 while (lotrs_ptr != NULL) {
4484 lotrs_tmpptr = duplotrs (lotrs_ptr);
4485 lotrs_tmpptr->NEXT = lotrs_rpt;
4486 lotrs_rpt = lotrs_tmpptr;
4487
4488 lotrs_ptr = lotrs_ptr->NEXT;
4489 }
4490 lotrs_rpt = (lotrs_list *) reverse ((chain_list *) lotrs_rpt);
4491 return (lotrs_rpt);
4492 }
4493
4494 /*##------------------------------------------------------------------##*/
4495 /* Function : duplotrs() */
4496 /* contents : duplicate a lotrs and return a pointer on the new */
4497 /* structure. */
4498 /* called func. : mbkalloc(), duplocon() */
4499 /* note : the DRAIN, SOURCE, GRID, BULK pointers are also duplicated */
4500 /*##------------------------------------------------------------------##*/
4501
4502 lotrs_list *duplotrs (lotrs_ptr)
4503 lotrs_list *lotrs_ptr;
4504 {
4505 lotrs_list *lotrs_rpt = NULL; /* Returned lotrs pointer */
4506 ptype_list *ptuser;
4507
4508 lotrs_rpt = (lotrs_list *) mbkalloc (sizeof (lotrs_list));
4509 lotrs_rpt->NEXT = NULL;
4510 lotrs_rpt->TRNAME = lotrs_ptr->TRNAME;
4511 lotrs_rpt->DRAIN = lotrs_ptr->DRAIN;
4512 lotrs_rpt->GRID = lotrs_ptr->GRID;
4513 lotrs_rpt->SOURCE = lotrs_ptr->SOURCE;
4514 lotrs_rpt->BULK = lotrs_ptr->BULK;
4515 lotrs_rpt->WIDTH = lotrs_ptr->WIDTH;
4516 lotrs_rpt->LENGTH = lotrs_ptr->LENGTH;
4517 lotrs_rpt->PS = lotrs_ptr->PS;
4518 lotrs_rpt->PD = lotrs_ptr->PD;
4519 lotrs_rpt->XS = lotrs_ptr->XS;
4520 lotrs_rpt->XD = lotrs_ptr->XD;
4521 lotrs_rpt->X = lotrs_ptr->X;
4522 lotrs_rpt->Y = lotrs_ptr->Y;
4523 lotrs_rpt->TYPE = lotrs_ptr->TYPE;
4524 lotrs_rpt->MODINDEX = lotrs_ptr->MODINDEX;
4525 lotrs_rpt->USER = NULL; /* The ptype_list is not duplicated */
4526
4527 if ((ptuser = getptype (lotrs_ptr->USER, OPT_PARAMS)) != NULL) {
4528 lotrs_rpt->USER = addptype (lotrs_rpt->USER, OPT_PARAMS, dupoptparamlst ((optparam_list *) ptuser->DATA));
4529 }
4530 if ((ptuser = getptype (lotrs_ptr->USER, TRANS_FIGURE)) != NULL) {
4531 lotrs_rpt->USER = addptype (lotrs_rpt->USER, TRANS_FIGURE, ptuser->DATA);
4532 }
4533
4534 return (lotrs_rpt);
4535 }
4536
4537 /*##------------------------------------------------------------------##*/
4538 /* Function : rduplotrs() */
4539 /* contents : duplicate a lotrs and return a pointer on the new */
4540 /* structure. The locon structures are duplicated but */
4541 /* the losig is kept as the original */
4542 /*##------------------------------------------------------------------##*/
4543
4544 lotrs_list *rduplotrs (lotrs_ptr)
4545 lotrs_list *lotrs_ptr;
4546 {
4547 lotrs_list *lotrs_rpt = NULL; /* Returned lotrs pointer */
4548
4549 lotrs_rpt = duplotrs(lotrs_ptr);
4550 lotrs_rpt->GRID = duplocon (lotrs_rpt->GRID);
4551 lotrs_rpt->GRID->ROOT = lotrs_rpt;
4552 lotrs_rpt->SOURCE = duplocon (lotrs_rpt->SOURCE);
4553 lotrs_rpt->SOURCE->ROOT = lotrs_rpt;
4554 lotrs_rpt->DRAIN = duplocon (lotrs_rpt->DRAIN);
4555 lotrs_rpt->DRAIN->ROOT = lotrs_rpt;
4556 if (lotrs_rpt->BULK) {
4557 lotrs_rpt->BULK = duplocon (lotrs_rpt->BULK);
4558 lotrs_rpt->BULK->ROOT = lotrs_rpt;
4559 }
4560 return (lotrs_rpt);
4561 }
4562
4563 loins_list *rduploins (loins_list *loins_ptr)
4564 {
4565 loins_list *loins_rpt = NULL; /* Returned loins pointer */
4566 locon_list *ptcon;
4567
4568 loins_rpt = duploins(loins_ptr);
4569 loins_rpt->LOCON = duploconlst (loins_rpt->LOCON);
4570 for (ptcon = loins_rpt->LOCON; ptcon; ptcon = ptcon->NEXT) {
4571 ptcon->ROOT = loins_rpt;
4572 }
4573 return (loins_rpt);
4574 }
4575
4576 /*##------------------------------------------------------------------##*/
4577 /* Function : duplosiglst() */
4578 /* contents : duplicate a losig_list and return a pointer on the new */
4579 /* structure, a pointer on BKSIG must be given. */
4580 /* called func. :duplosig(), reverse(), */
4581 /*##------------------------------------------------------------------##*/
4582
4583 losig_list *duplosiglst (losig_list *losig_ptr, lofig_list *lf)
4584 {
4585 losig_list *losig_rpt = NULL; /* Returned losig pointer */
4586 losig_list *losig_tmpptr = NULL; /* Temporary pointer */
4587
4588 while (losig_ptr != NULL) {
4589 losig_tmpptr = duplosig (losig_ptr, lf);
4590 losig_tmpptr->NEXT = losig_rpt;
4591 losig_rpt = losig_tmpptr;
4592
4593 losig_ptr = losig_ptr->NEXT;
4594 }
4595 losig_rpt = (losig_list *) reverse ((chain_list *) losig_rpt);
4596 return (losig_rpt);
4597 }
4598
4599
4600 /*##------------------------------------------------------------------##*/
4601 /* Function : duplosig() */
4602 /* contents : duplicate a losig and return a pointer on the new */
4603 /* structure, a pointer on the BKSIG must be given. */
4604 /* called func. : mbkalloc, addptype, dupchainlst */
4605 /*##------------------------------------------------------------------##*/
4606
4607 losig_list *duplosig (losig_list *losig_ptr, lofig_list *lf)
4608 {
4609 long index = losig_ptr->INDEX;
4610 losig_list *ptsig = NULL;
4611 ptsig=mbk_NewBKSIG_getindex(lf, index);
4612 /* check index unicity */
4613 if (ptsig->INDEX != 0L) avt_errmsg(MBK_ERRMSG, "015", AVT_FATAL, index);
4614
4615 ptsig->NEXT = NULL;
4616 ptsig->NAMECHAIN = dupchainlst (losig_ptr->NAMECHAIN);
4617 ptsig->PRCN = NULL;
4618 ptsig->INDEX = losig_ptr->INDEX;
4619 ptsig->USER = NULL;
4620 ptsig->PRCN = NULL; /* The rc data is not duplicated */
4621 ptsig->TYPE = losig_ptr->TYPE; /* The ptype_list is not duplicated */
4622 ptsig->RCNCACHE = 0;
4623 ptsig->ALIMFLAGS= losig_ptr->ALIMFLAGS;
4624
4625 duplosigalim (losig_ptr, ptsig);
4626 mbk_dupvcardnodes(losig_ptr, ptsig);
4627
4628 if (TRACE_MODE == 'Y') {
4629 (void)fprintf (stdout, "--- mbk --- duplosig : %ld ", index);
4630 if (ptsig->NAMECHAIN)
4631 if (ptsig->NAMECHAIN->DATA)
4632 (void)fprintf (stdout, "name : %s", (char *)((chain_list *) (ptsig->NAMECHAIN))->DATA);
4633 (void)fprintf (stdout, "\n");
4634 }
4635
4636 return ptsig;
4637 }
4638
4639 /*##------------------------------------------------------------------##*/
4640 /* Function : duplofiglst() */
4641 /* contents : duplicate a lofig list and return a pointer on the new */
4642 /* structure. */
4643 /* called func. : duplofig(), reverse(), */
4644 /*##------------------------------------------------------------------##*/
4645
4646 lofig_list *duplofiglst (lofig_ptr)
4647 lofig_list *lofig_ptr;
4648 {
4649 lofig_list *lofig_rpt = NULL; /* Returned lofig pointer */
4650 lofig_list *lofig_tmpptr = NULL; /* Temporary pointer */
4651
4652 while (lofig_ptr != NULL) {
4653 lofig_tmpptr = duplofig (lofig_ptr);
4654 lofig_tmpptr->NEXT = lofig_rpt;
4655 lofig_rpt = lofig_tmpptr;
4656
4657 lofig_ptr = lofig_ptr->NEXT;
4658 }
4659 lofig_rpt = (lofig_list *) reverse ((chain_list *) lofig_rpt);
4660 return (lofig_rpt);
4661 }
4662
4663 /*##------------------------------------------------------------------##*/
4664 /* Function : duplofig() */
4665 /* contents : duplicate a lofig and return a pointer on the new */
4666 /* structure. */
4667 /* called func. : mbkalloc(), dupchainlst(), */
4668 /* note : the LOCON, LOSIG, BKSIG, LOINS, LOTRS pointers are */
4669 /* also duplicated */
4670 /*##------------------------------------------------------------------##*/
4671
4672 lofig_list *duplofig (lofig_ptr)
4673 lofig_list *lofig_ptr;
4674 {
4675 lofig_list *lofig_rpt = NULL; /* Returned lofig pointer */
4676 ptype_list *ptuser;
4677 lofiginfo *lfif, *lfif0;
4678
4679 lofig_rpt = (lofig_list *) (mbkalloc (sizeof (lofig_list)));
4680 mbk_init_NewBKSIG(&lofig_rpt->BKSIG);
4681 lofig_rpt->USER = NULL; /* The ptype_list is not duplicated */
4682 setsigsize (lofig_rpt, getsigsize (lofig_ptr));
4683 lofig_rpt->NEXT = NULL;
4684 lofig_rpt->MODELCHAIN = dupchainlst (lofig_ptr->MODELCHAIN);
4685 lofig_rpt->LOCON = lofig_ptr->LOCON;
4686 lofig_rpt->LOSIG = lofig_ptr->LOSIG;
4687 memcpy(&lofig_rpt->BKSIG, &lofig_ptr->BKSIG, sizeof(NewBKSIG));
4688 lofig_rpt->LOINS = lofig_ptr->LOINS;
4689 lofig_rpt->LOTRS = lofig_ptr->LOTRS;
4690 lofig_rpt->NAME = lofig_ptr->NAME;
4691 lofig_rpt->MODE = lofig_ptr->MODE;
4692
4693 if ((ptuser = getptype (lofig_ptr->USER, OPT_PARAMS)) != NULL) {
4694 lofig_rpt->USER = addptype (lofig_rpt->USER, OPT_PARAMS, dupoptparamlst ((optparam_list *) ptuser->DATA));
4695 }
4696
4697 if ((lfif=mbk_getlofiginfo(lofig_ptr, 0))!=NULL)
4698 {
4699 lfif0=mbk_getlofiginfo(lofig_rpt, 1);
4700 memcpy(lfif0, lfif, sizeof(lofiginfo));
4701 }
4702
4703 return (lofig_rpt);
4704 }
4705
4706 /*##------------------------------------------------------------------##*/
4707 /* Function : rduplofig() */
4708 /* contents : recursively duplicate a lofig and return a pointer on */
4709 /* the new structure. This structure is the entirely */
4710 /* double of the lofig duplicated. Except, that all the */
4711 /* USER fields are empty. */
4712 /* called func. : mbkalloc(), */
4713 /*##------------------------------------------------------------------##*/
4714
4715 lofig_list *rduplofig (lofig_ptr)
4716 lofig_list *lofig_ptr;
4717 {
4718 lofig_list *lofig_rpt = NULL; /* Returned lofig pointer */
4719 locon_list *locon_pt = NULL;
4720 loins_list *loins_pt = NULL;
4721 lotrs_list *lotrs_pt = NULL;
4722 losig_list *losig_pt = NULL;
4723 chain_list *headctc;
4724 chain_list *scanchain;
4725 loctc_list *ptctc, *dupctc;
4726 ptype_list *ptuser;
4727 long index = 0;
4728 int cnt;
4729
4730 lofig_rpt = duplofig (lofig_ptr);
4731 mbk_init_NewBKSIG(&lofig_rpt->BKSIG);
4732
4733 lofig_rpt->LOSIG = duplosiglst (lofig_rpt->LOSIG, lofig_rpt);
4734 lofig_rpt->LOCON = duploconlst (lofig_rpt->LOCON);
4735 lofig_rpt->LOINS = duploinslst (lofig_rpt->LOINS);
4736 lofig_rpt->LOTRS = duplotrslst (lofig_rpt->LOTRS);
4737
4738 /* Now verify and restitute the coherence of the figure */
4739
4740 /* Restitute coherence in the LOTRS List */
4741 lotrs_pt = lofig_rpt->LOTRS;
4742 while (lotrs_pt != NULL) {
4743 lotrs_pt->GRID = duplocon (lotrs_pt->GRID);
4744 locon_pt = lotrs_pt->GRID;
4745 while (locon_pt != NULL) {
4746 index = (locon_pt->SIG)->INDEX;
4747 locon_pt->SIG = getlosig (lofig_rpt, index);
4748 locon_pt->ROOT = (void *)lotrs_pt;
4749
4750 locon_pt = locon_pt->NEXT;
4751 }
4752
4753 lotrs_pt->DRAIN = duplocon (lotrs_pt->DRAIN);
4754 locon_pt = lotrs_pt->DRAIN;
4755 while (locon_pt != NULL) {
4756 index = (locon_pt->SIG)->INDEX;
4757 locon_pt->SIG = getlosig (lofig_rpt, index);
4758 locon_pt->ROOT = (void *)lotrs_pt;
4759
4760 locon_pt = locon_pt->NEXT;
4761 }
4762
4763 lotrs_pt->SOURCE = duplocon (lotrs_pt->SOURCE);
4764 locon_pt = lotrs_pt->SOURCE;
4765 while (locon_pt != NULL) {
4766 index = (locon_pt->SIG)->INDEX;
4767 locon_pt->SIG = getlosig (lofig_rpt, index);
4768 locon_pt->ROOT = (void *)lotrs_pt;
4769
4770 locon_pt = locon_pt->NEXT;
4771 }
4772
4773 // zinaps le 20/7/2002
4774 if (lotrs_pt->BULK) {
4775 lotrs_pt->BULK = duplocon (lotrs_pt->BULK);
4776 }
4777 else
4778 lotrs_pt->BULK = NULL;
4779 locon_pt = lotrs_pt->BULK;
4780 while (locon_pt != NULL) {
4781 if (locon_pt->SIG) {
4782 index = (locon_pt->SIG)->INDEX;
4783 locon_pt->SIG = getlosig (lofig_rpt, index);
4784 }
4785 else {
4786 locon_pt->SIG = NULL;
4787 }
4788 locon_pt->ROOT = (void *)lotrs_pt;
4789
4790 locon_pt = locon_pt->NEXT;
4791 }
4792
4793 lotrs_pt = lotrs_pt->NEXT;
4794 }
4795
4796 /* Restitute coherence in the LOINS List */
4797 loins_pt = lofig_rpt->LOINS;
4798 while (loins_pt != NULL) {
4799 loins_pt->LOCON = duploconlst (loins_pt->LOCON);
4800 locon_pt = loins_pt->LOCON;
4801 while (locon_pt != NULL) {
4802 index = (locon_pt->SIG)->INDEX;
4803 locon_pt->SIG = getlosig (lofig_rpt, index);
4804 locon_pt->ROOT = (void *)loins_pt;
4805
4806 locon_pt = locon_pt->NEXT;
4807 }
4808 loins_pt = loins_pt->NEXT;
4809 }
4810
4811 /* Restitute coherence in the LOCON List */
4812 locon_pt = lofig_rpt->LOCON;
4813 while (locon_pt != NULL) {
4814 index = (locon_pt->SIG)->INDEX;
4815 locon_pt->SIG = getlosig (lofig_rpt, index);
4816 locon_pt->ROOT = (void *)lofig_rpt;
4817
4818 locon_pt = locon_pt->NEXT;
4819 }
4820
4821 /* Duplicate rc data */
4822 for (losig_pt = lofig_ptr->LOSIG; losig_pt; losig_pt = losig_pt->NEXT)
4823 duplorcnet (getlosig (lofig_rpt, losig_pt->INDEX), losig_pt);
4824
4825 headctc = getallctc (lofig_ptr);
4826 for (scanchain = headctc; scanchain; scanchain = scanchain->NEXT) {
4827 ptctc = (loctc_list *) scanchain->DATA;
4828 dupctc = addloctc (getlosig (lofig_rpt, ptctc->SIG1->INDEX), ptctc->NODE1,
4829 getlosig (lofig_rpt, ptctc->SIG2->INDEX), ptctc->NODE2, ptctc->CAPA);
4830 if ((ptuser = getptype (ptctc->USER, OPT_PARAMS)))
4831 dupctc->USER = addptype (dupctc->USER, OPT_PARAMS, dupoptparamlst ((optparam_list *) ptuser->DATA));
4832 if ((cnt=rcn_isCapaDiode(ptctc))!=0) rcn_setCapaDiode(dupctc, cnt);
4833 if ((ptuser=getptype(ptctc->USER, MSL_CAPANAME))!=NULL)
4834 dupctc->USER = addptype (dupctc->USER, MSL_CAPANAME, ptuser->DATA);
4835
4836 }
4837 freechain (headctc);
4838
4839 return (lofig_rpt);
4840 }
4841
4842 /* sort routines :
4843 connectors and signals may have to be sorted by name for some
4844 language purposes. */
4845
4846 static char Buffer0[255]; /* may be of use for other functions */
4847
4848 static int connectorcmp (flc, slc)
4849 locon_list **flc, **slc;
4850 {
4851 return naturalstrcmp ((*slc)->NAME, (*flc)->NAME);
4852 }
4853
4854 void sortlocon (connectors)
4855 locon_list **connectors;
4856 {
4857 long n, i;
4858 locon_list *lc, **tc;
4859
4860 if (!connectors || !(*connectors))
4861 return;
4862
4863 /* first :
4864 count connectors. */
4865 for (n = 0, lc = *connectors; lc; lc = lc->NEXT)
4866 n++;
4867 tc = (locon_list **) mbkalloc (n * sizeof (locon_list *));
4868 for (n = 0, lc = *connectors; lc; lc = lc->NEXT)
4869 tc[n++] = lc;
4870 /* second :
4871 sort them. */
4872 qsort ((void *)tc, n, sizeof (locon_list *), connectorcmp);
4873 /* tables :
4874 the last element of the table is t[n - 1].
4875 relink the list in the sorted order. */
4876 n--;
4877 *connectors = tc[0];
4878 for (i = 0; i < n; i++)
4879 tc[i]->NEXT = tc[i + 1];
4880 tc[n]->NEXT = (locon_list *) NULL;
4881 mbkfree ((void *)tc);
4882 }
4883
4884 static int signalcmp (fls, sls)
4885 losig_list **fls, **sls;
4886 {
4887 return naturalstrcmp (getsigname (*fls), getsigname (*sls));
4888 }
4889
4890 void sortlosig (signals)
4891 losig_list **signals;
4892 {
4893 long n, i;
4894 losig_list *lc, **tc;
4895
4896 if (!signals || !(*signals))
4897 return;
4898
4899 /* first :
4900 count signals. */
4901 for (n = 0, lc = *signals; lc; lc = lc->NEXT)
4902 n++;
4903 tc = (losig_list **) mbkalloc (n * sizeof (losig_list *));
4904 for (n = 0, lc = *signals; lc; lc = lc->NEXT)
4905 tc[n++] = lc;
4906 /* second :
4907 sort them. */
4908 qsort ((void *)tc, n, sizeof (losig_list *), signalcmp);
4909 /* tables :
4910 the last element of the table is t[n - 1].
4911 relink the list in the sorted order. */
4912 n--;
4913 *signals = tc[0];
4914 for (i = 0; i < n; i++)
4915 tc[i]->NEXT = tc[i + 1];
4916 tc[n]->NEXT = (losig_list *) NULL;
4917 mbkfree ((void *)tc);
4918 }
4919
4920 /* checking :
4921 the validity of a list of connectors for vectorization purposes
4922 is to be checked for some file formats, so let's do it.
4923 The algorithm checks that :
4924 vectorized radical do not appear on themselves
4925 vectorized connectors are all together and ordered properly */
4926 #define HTSIZE 200
4927 int checkloconorder (c)
4928 locon_list *c;
4929 {
4930 char *s = NULL, *t = NULL;
4931 ht *table;
4932 int first = 1, previous = 0, delta = 0, current = 0;
4933
4934 table = addht (HTSIZE);
4935 while (c) {
4936 /* vectorized ?
4937 no. */
4938 if ((s = strchr (c->NAME, ' ')) == NULL) {
4939 avoid_redundancy:
4940 if (sethtitem (table, (void *)c->NAME, 0)) {
4941 delht (table);
4942 avt_errmsg(MBK_ERRMSG, "016", AVT_FATAL, c->NAME);
4943 return 1;
4944 }
4945 first = 1;
4946 c = c->NEXT;
4947 }
4948 else {
4949 while (c) {
4950 int i = 1;
4951 /* redundancy :
4952 I'ven't found an elegant way to do that, too bad. */
4953 if (!s)
4954 if ((s = strchr (c->NAME, ' ')) == NULL)
4955 goto avoid_redundancy;
4956 /* Temporary change :
4957 alter the string contents just a microsecond. */
4958 *s = '\0';
4959 strcpy (Buffer0, c->NAME);
4960 *s = ' ';
4961 while (*(s + i) && isdigit ((int)*(s + i)))
4962 i++;
4963 if (*(s + i)) {
4964 delht (table);
4965 avt_errmsg(MBK_ERRMSG, "017", AVT_FATAL, Buffer0, s + 1, c->NAME);
4966 return 1;
4967 }
4968 current = atoi (s + 1);
4969 s = NULL;
4970 /* first :
4971 the name is not yet known. so I store it.
4972 we do that each time a new vector is encountered. */
4973 if (first) {
4974 its_first:
4975 if (sethtitem (table, (void *)(t = namealloc (Buffer0)), 0)) {
4976 delht (table);
4977 avt_errmsg(MBK_ERRMSG, "016", AVT_FATAL, Buffer0);
4978 return 1;
4979 }
4980 delta = first = 0;
4981 previous = current;
4982 c = c->NEXT;
4983 }
4984 else { /* let's see if it's a good vhdl legal vector */
4985 /* its a new vector :
4986 in fact this vector follows an other vector! */
4987 if (t != namealloc (Buffer0))
4988 goto its_first;
4989 if (!delta)
4990 delta = previous - current;
4991 else if (delta != previous - current) {
4992 delht (table);
4993 avt_errmsg(MBK_ERRMSG, "018", AVT_FATAL, Buffer0, Buffer0, previous, Buffer0, current);
4994 }
4995 if (delta != 1 && delta != -1) {
4996 delht (table);
4997 avt_errmsg(MBK_ERRMSG, "018", AVT_FATAL, c->NAME, Buffer0, previous, Buffer0, current);
4998 }
4999 previous = current;
5000 c = c->NEXT;
5001 }
5002 }
5003 }
5004 }
5005 delht (table);
5006 return 0;
5007 }
5008
5009 //_____________________________________________________
5010
5011 int bigcomp (const void *p1, const void *p2)
5012 {
5013 losig_list *sig1, *sig2;
5014 int index1, index2;
5015
5016 sig1 = *(losig_list **) p1;
5017 sig2 = *(losig_list **) p2;
5018
5019 index1 = vectorindex ((char *)sig1->NAMECHAIN->DATA);
5020 index2 = vectorindex ((char *)sig2->NAMECHAIN->DATA);
5021
5022 if (index1 > index2)
5023 return -1;
5024 if (index1 < index2)
5025 return 1;
5026
5027 return 0;
5028 }
5029
5030 //_____________________________________________________
5031
5032 int littlecomp (const void *p1, const void *p2)
5033 {
5034 losig_list *sig1, *sig2;
5035 int index1, index2;
5036
5037 sig1 = *(losig_list **) p1;
5038 sig2 = *(losig_list **) p2;
5039
5040 index1 = vectorindex ((char *)sig1->NAMECHAIN->DATA);
5041 index2 = vectorindex ((char *)sig2->NAMECHAIN->DATA);
5042
5043 if (index1 > index2)
5044 return 1;
5045 if (index1 < index2)
5046 return -1;
5047
5048 return 0;
5049 }
5050
5051
5052 //_____________________________________________________
5053
5054 chain_list *sort_sigs (losig_list * sig_list, ht * endht)
5055 {
5056 char *radix, *stocked_sig_radix;
5057 losig_list *sig, *stocked_sig;
5058 chain_list *ch, *ch1, *sigchain = NULL;
5059 ht *htab;
5060 losig_list **sig_array;
5061 chain_list *ordered_list = NULL;
5062 long n;
5063 int i, endianess;
5064
5065 /* Sort by name */
5066
5067 htab = addht (100);
5068
5069 for (sig = sig_list; sig; sig = sig->NEXT) {
5070 radix = vectorradical (sig->NAMECHAIN->DATA);
5071 if (gethtitem (htab, radix) == EMPTYHT) {
5072 sigchain = addchain (sigchain, addchain (NULL, sig));
5073 addhtitem (htab, radix, 0);
5074 }
5075 else {
5076 for (ch = sigchain; ch; ch = ch->NEXT) {
5077 stocked_sig = (losig_list *) ((chain_list *) ch->DATA)->DATA;
5078 stocked_sig_radix = vectorradical ((char *)stocked_sig->NAMECHAIN->DATA);
5079 if (stocked_sig_radix == radix) {
5080 ch->DATA = addchain (ch->DATA, sig);
5081 break;
5082 }
5083 }
5084 }
5085 }
5086
5087 delht (htab);
5088
5089 /* Create arrays and sort */
5090
5091 for (ch = sigchain; ch; ch = ch->NEXT) {
5092 n = 0;
5093 for (ch1 = (chain_list *) ch->DATA; ch1; ch1 = ch1->NEXT)
5094 n++;
5095 sig_array = (losig_list **) mbkalloc ((n + 1) * sizeof (losig_list *));
5096 i = 0;
5097 sig_array[i++] = (losig_list *) n;
5098 for (ch1 = (chain_list *) ch->DATA; ch1; ch1 = ch1->NEXT)
5099 sig_array[i++] = (losig_list *) ch1->DATA;
5100 freechain ((chain_list *) ch->DATA);
5101 ch->DATA = sig_array;
5102 if (n > 1) {
5103 if (!endht)
5104 qsort (&sig_array[1], n, sizeof (losig_list *), littlecomp);
5105 else {
5106 radix = vectorradical ((char *)((losig_list *) (((chain_list *) ch->DATA)->DATA))->NAMECHAIN->DATA);
5107 if ((endianess = gethtitem (endht, radix)) != EMPTYHT) {
5108 if (endianess == MBK_LITTLE_ENDIAN)
5109 qsort (&sig_array[1], n, sizeof (losig_list *), littlecomp);
5110 else if (endianess == MBK_BIG_ENDIAN)
5111 qsort (&sig_array[1], n, sizeof (losig_list *), bigcomp);
5112 else
5113 qsort (&sig_array[1], n, sizeof (losig_list *), littlecomp);
5114 }
5115 else
5116 qsort (&sig_array[1], n, sizeof (losig_list *), littlecomp);
5117 }
5118 }
5119 }
5120
5121 /* Reorder losigs */
5122
5123 for (ch = sigchain; ch; ch = ch->NEXT) {
5124 sig_array = (losig_list **) ch->DATA;
5125 for (i = 1; i <= (long)sig_array[0]; i++)
5126 ordered_list = addchain (ordered_list, sig_array[i]);
5127 mbkfree (sig_array);
5128 }
5129
5130 freechain (sigchain);
5131 return ordered_list;
5132 }
5133
5134 void vectorbounds (lofig_list * ptfig, char *radical, int *begin, int *end)
5135 {
5136 locon_list *ptcon;
5137 int counting = 0, start=0;
5138
5139 ptcon = ptfig->LOCON;
5140 *begin=-1;
5141 *end=-1;
5142
5143 while (ptcon)
5144 {
5145 if (vectorradical (ptcon->NAME) == radical)
5146 {
5147 counting=vectorindex(ptcon->NAME);
5148 if (counting==-1) return;
5149 if (*begin==-1) *begin=counting;
5150 *end=counting;
5151 start=1;
5152 }
5153 else if (start) break;
5154 ptcon = ptcon->NEXT;
5155 }
5156 }
5157
5158 void ClearLOTRSLoconFlags (lotrs_list * tr)
5159 {
5160 tr->GRID->FLAGS = 0;
5161 tr->SOURCE->FLAGS = 0;
5162 tr->DRAIN->FLAGS = 0;
5163 if (tr->BULK != NULL)
5164 tr->BULK->FLAGS = 0;
5165 }
5166
5167 void ClearAllLOTRSLoconFlags (lotrs_list * tr)
5168 {
5169 while (tr != NULL) {
5170 tr->GRID->FLAGS = 0;
5171 tr->SOURCE->FLAGS = 0;
5172 tr->DRAIN->FLAGS = 0;
5173 if (tr->BULK != NULL)
5174 tr->BULK->FLAGS = 0;
5175 tr = tr->NEXT;
5176 }
5177 }
5178
5179 void ClearAllLoconFlags (locon_list * lc)
5180 {
5181 while (lc != NULL) {
5182 lc->FLAGS = 0;
5183 lc = lc->NEXT;
5184 }
5185 }
5186
5187 void ClearAllLOINSLoconFlags (loins_list * li)
5188 {
5189 while (li != NULL) {
5190 ClearAllLoconFlags (li->LOCON);
5191 li = li->NEXT;
5192 }
5193 }
5194
5195 void ClearLOFIGLoconFlags (lofig_list * lf)
5196 {
5197 ClearAllLoconFlags (lf->LOCON);
5198 ClearAllLOINSLoconFlags (lf->LOINS);
5199 ClearAllLOTRSLoconFlags (lf->LOTRS);
5200 }
5201
5202 void freeflatmodel (lofig_list * fig)
5203 {
5204 losig_list *ptsig;
5205 locon_list *ptcon;
5206 lotrs_list *pttrs;
5207 void *ptold = NULL;
5208
5209 if (fig->LOINS)
5210 return;
5211 if (getptype (fig->USER, LOFIG_LOCK))
5212 return;
5213
5214 freectclist (fig, NULL);
5215 for (ptsig = fig->LOSIG; ptsig; ptsig = ptsig->NEXT) {
5216 freechain (ptsig->NAMECHAIN);
5217 if (ptsig->PRCN)
5218 freelorcnet (ptsig);
5219 dellosiguser (ptsig);
5220 }
5221
5222 mbk_free_NewBKSIG(&fig->BKSIG);
5223 for (ptcon = fig->LOCON; ptcon; ptcon = (locon_list *) ptold) {
5224 ptold = (void *)ptcon->NEXT;
5225 delloconuser (ptcon);
5226 mbkfree (ptcon);
5227 }
5228
5229 for (pttrs = fig->LOTRS; pttrs; pttrs = (lotrs_list *) ptold) {
5230 delloconuser (pttrs->GRID);
5231 delloconuser (pttrs->SOURCE);
5232 delloconuser (pttrs->DRAIN);
5233 if (pttrs->BULK) {
5234 delloconuser (pttrs->BULK);
5235 mbkfree (pttrs->BULK);
5236 }
5237
5238 mbkfree (pttrs->GRID);
5239 mbkfree (pttrs->SOURCE);
5240 mbkfree (pttrs->DRAIN);
5241 // mbkfree((void *)pttrs->BULK);
5242 ptold = pttrs->NEXT;
5243 dellotrsuser (pttrs);
5244 mbkfree (pttrs);
5245 }
5246
5247 dellofiguser (fig);
5248 freechain (fig->MODELCHAIN);
5249 mbkfree (fig);
5250 }
5251
5252
5253 static void merge_trans (lotrs_list * pttrans, lotrs_list * pt2trans)
5254 {
5255 ptype_list *ptuser;
5256
5257 if ((ptuser = getptype (pttrans->USER, MBK_TRANS_PARALLEL)) == NULL) {
5258 pttrans->USER = addptype (pttrans->USER, MBK_TRANS_PARALLEL, addchain (NULL, pttrans));
5259 ptuser = pttrans->USER;
5260 }
5261 ptuser->DATA = addchain ((chain_list *) ptuser->DATA, pt2trans);
5262 }
5263
5264 /****************************************************************************
5265 * function mbkTranscompare(); *
5266 ****************************************************************************/
5267 static int mbkTransCompare (const void *elem1, const void *elem2)
5268 {
5269 long sig1, sig2;
5270 lotrs_list *t1, *t2;
5271
5272 t1 = *(lotrs_list **) elem1;
5273 t2 = *(lotrs_list **) elem2;
5274 sig1 = (long)t1->SOURCE->SIG + (long)t1->DRAIN->SIG;
5275 sig2 = (long)t2->SOURCE->SIG + (long)t2->DRAIN->SIG;
5276
5277 if (sig1 > sig2) return 1;
5278 else if (sig1 < sig2) return -1;
5279
5280 if (t1->LENGTH > t2->LENGTH) return 1;
5281 else if (t1->LENGTH < t2->LENGTH) return -1;
5282
5283 if (t1->TRNAME!=NULL && t2->TRNAME!=NULL)
5284 return mbk_casestrcmp(t1->TRNAME, t2->TRNAME);
5285
5286 return 0;
5287 }
5288
5289 static int mbkSameBBox(lotrs_list *tr0, lotrs_list *tr1)
5290 {
5291 ptype_list *pt, *pt1;
5292 pt=getptype(tr0->USER, BBOX_AS_UNUSED);
5293 pt1=getptype(tr1->USER, BBOX_AS_UNUSED);
5294 if ((pt==NULL && pt1==NULL) || (pt!=NULL && pt1!=NULL && pt->DATA==pt1->DATA)) return 1;
5295 return 0;
5296 }
5297
5298 /****************************************************************************
5299 * function mbk_removeparallel(); *
5300 ****************************************************************************/
5301 long mbk_removeparallel (lofig_list * ptlofig, int remove)
5302 {
5303 lotrs_list *pttrans = NULL;
5304 lotrs_list *pt2trans = NULL;
5305 lotrs_list *ptprevtrans = NULL;
5306 lotrs_list *ptnexttrans = NULL;
5307 losig_list *ptlosig = NULL;
5308 locon_list *ptlocon = NULL;
5309 chain_list *ptchain;
5310 chain_list *loconchain, *gridchain;
5311 lotrs_list **gridtable;
5312 ptype_list *ptuser;
5313 long numparallel = 0L;
5314 long signature = 0L;
5315 int numgrids = 0;
5316 int parallel = 0;
5317 int transtodel;
5318 int i, j;
5319
5320 lofigchain (ptlofig);
5321 for (ptlosig = ptlofig->LOSIG; ptlosig; ptlosig = ptlosig->NEXT) {
5322 gridchain = NULL;
5323 numgrids = 0;
5324 loconchain = (chain_list *) getptype (ptlosig->USER, LOFIGCHAIN)->DATA;
5325 for (ptchain = loconchain; ptchain; ptchain = ptchain->NEXT) {
5326 ptlocon = (locon_list *) ptchain->DATA;
5327 if (ptlocon->TYPE == 'T' && ptlocon->NAME == MBK_GRID_NAME) {
5328 gridchain = addchain (gridchain, ptlocon->ROOT);
5329 numgrids++;
5330 }
5331 }
5332 if (numgrids > 0)
5333 gridtable = (lotrs_list **) mbkalloc (numgrids * sizeof (lotrs_list *));
5334 i = 0;
5335 for (ptchain = gridchain; ptchain; ptchain = ptchain->NEXT) {
5336 pttrans = (lotrs_list *) ptchain->DATA;
5337 gridtable[i++] = pttrans;
5338 }
5339 if (numgrids > 2)
5340 qsort (gridtable, numgrids, sizeof (lotrs_list *), mbkTransCompare);
5341 i = 0;
5342 for (i = 0; i < numgrids; i++) {
5343 pttrans = gridtable[i];
5344 if (getptype (pttrans->USER, MBK_TRANS_MARK) != NULL)
5345 continue;
5346 signature = (long)pttrans->SOURCE->SIG + (long)pttrans->DRAIN->SIG;
5347 for (j = i + 1; j < numgrids; j++) {
5348 parallel = 0;
5349 pt2trans = gridtable[j];
5350 if (signature != (long)pt2trans->SOURCE->SIG + (long)pt2trans->DRAIN->SIG)
5351 break;
5352 if ((pt2trans->DRAIN->SIG == pttrans->DRAIN->SIG)
5353 && (pt2trans->TYPE == pttrans->TYPE)
5354 && (pt2trans->SOURCE->SIG == pttrans->SOURCE->SIG)
5355 && mbkSameBBox(pt2trans, pttrans)) {
5356 /* transistors in parallel */
5357 parallel = 1;
5358 }
5359 else if ((pt2trans->SOURCE->SIG == pttrans->DRAIN->SIG)
5360 && (pt2trans->TYPE == pttrans->TYPE)
5361 && (pt2trans->DRAIN->SIG == pttrans->SOURCE->SIG)
5362 && mbkSameBBox(pt2trans, pttrans)) {
5363 /* transistors in parallel */
5364 parallel = 1;
5365 }
5366 if (parallel) {
5367 merge_trans (pttrans, pt2trans);
5368 numparallel++;
5369 if (remove) {
5370 pt2trans->USER = addptype (pt2trans->USER, MBK_TRANS_MARK, 0);
5371 }
5372 }
5373 }
5374 }
5375 if (gridchain != NULL)
5376 freechain (gridchain);
5377 if (numgrids > 0)
5378 mbkfree (gridtable);
5379 }
5380 if (numparallel > 0) {
5381 for (pttrans = ptlofig->LOTRS; pttrans; pttrans = pttrans->NEXT) {
5382 if ((ptuser = getptype (pttrans->USER, MBK_TRANS_PARALLEL)) != NULL
5383 && getptype (pttrans->USER, MBK_TRANS_MARK) == NULL) {
5384 /* make sure that non-instance is at beginning of list */
5385 ptuser->DATA = reverse((chain_list *)ptuser->DATA);
5386 }
5387 }
5388 }
5389
5390 if (remove) {
5391 ptprevtrans = NULL;
5392 transtodel = 0;
5393 for (pttrans = ptlofig->LOTRS; pttrans; pttrans = ptnexttrans) {
5394 ptnexttrans = pttrans->NEXT;
5395 if (getptype (pttrans->USER, MBK_TRANS_MARK) != NULL) {
5396 if (ptprevtrans == NULL) {
5397 ptlofig->LOTRS = ptnexttrans;
5398 }
5399 else
5400 ptprevtrans->NEXT = ptnexttrans;
5401 transtodel = 1;
5402 }
5403 else
5404 ptprevtrans = pttrans;
5405 }
5406
5407 if (transtodel)
5408 lofigchain (ptlofig);
5409 }
5410
5411 return numparallel;
5412 }
5413
5414 /****************************************************************************
5415 * function mbk_restoreparallel(); *
5416 ****************************************************************************/
5417 void mbk_restoreparallel (lofig_list * ptlofig)
5418 {
5419 lotrs_list *pttrans;
5420 lotrs_list *ptparatrans;
5421 ptype_list *ptuser;
5422 chain_list *transchain;
5423 chain_list *ptchain;
5424 int changed = 0;
5425
5426 for (pttrans = ptlofig->LOTRS; pttrans; pttrans = pttrans->NEXT) {
5427 if ((ptuser = getptype (pttrans->USER, MBK_TRANS_PARALLEL)) != NULL) {
5428 transchain = (chain_list *) ptuser->DATA;
5429 for (ptchain = transchain; ptchain; ptchain = ptchain->NEXT) {
5430 ptparatrans = (lotrs_list *) ptchain->DATA;
5431 if (ptparatrans == pttrans)
5432 continue;
5433 /* if not marked then already restored */
5434 if (getptype (ptparatrans->USER, MBK_TRANS_MARK) == NULL)
5435 return;
5436 ptparatrans->USER = delptype (ptparatrans->USER, MBK_TRANS_MARK);
5437 changed = 1;
5438 ptparatrans->NEXT = ptlofig->LOTRS;
5439 ptlofig->LOTRS = ptparatrans;
5440 }
5441 }
5442 }
5443 if (changed)
5444 lofigchain (ptlofig);
5445 }
5446
5447 /****************************************************************************
5448 * function mbk_markparallel(); *
5449 ****************************************************************************/
5450 void mbk_markparallel (lofig_list * ptlofig)
5451 {
5452 lotrs_list *pttrans;
5453 lotrs_list *ptparatrans;
5454 ptype_list *ptuser;
5455 chain_list *transchain;
5456 chain_list *ptchain;
5457
5458 for (pttrans = ptlofig->LOTRS; pttrans; pttrans = pttrans->NEXT) {
5459 if (getptype (pttrans->USER, MBK_TRANS_MARK) != NULL) continue;
5460 if ((ptuser = getptype (pttrans->USER, MBK_TRANS_PARALLEL)) != NULL) {
5461 transchain = (chain_list *) ptuser->DATA;
5462 for (ptchain = transchain->NEXT; ptchain; ptchain = ptchain->NEXT) {
5463 ptparatrans = (lotrs_list *) ptchain->DATA;
5464 ptparatrans->USER = addptype (ptparatrans->USER, MBK_TRANS_MARK, 0);
5465 }
5466 }
5467 }
5468 }
5469
5470 /****************************************************************************
5471 * function mbk_unmarkparallel(); *
5472 ****************************************************************************/
5473 void mbk_unmarkparallel (lofig_list * ptlofig)
5474 {
5475 lotrs_list *pttrans;
5476
5477 for (pttrans = ptlofig->LOTRS; pttrans; pttrans = pttrans->NEXT) {
5478 if (getptype (pttrans->USER, MBK_TRANS_MARK) != NULL) {
5479 pttrans->USER = delptype (pttrans->USER, MBK_TRANS_MARK);
5480 }
5481 }
5482 }
5483
5484 /****************************************************************************
5485 * function mbk_freeparallel(); *
5486 ****************************************************************************/
5487 void mbk_freeparallel (lofig_list * ptlofig)
5488 {
5489 lotrs_list *pttrans;
5490 lotrs_list *ptparatrans;
5491 ptype_list *ptuser;
5492 chain_list *transchain;
5493 chain_list *ptchain;
5494
5495 for (pttrans = ptlofig->LOTRS; pttrans; pttrans = pttrans->NEXT) {
5496 if ((ptuser = getptype (pttrans->USER, MBK_TRANS_PARALLEL)) != NULL) {
5497 transchain = (chain_list *) ptuser->DATA;
5498 for (ptchain = transchain; ptchain; ptchain = ptchain->NEXT) {
5499 ptparatrans = (lotrs_list *) ptchain->DATA;
5500 ptparatrans->USER=testanddelptype(ptparatrans->USER, MBK_TRANS_PARALLEL);
5501 // ptparatrans->USER = delptype (ptparatrans->USER, MBK_TRANS_PARALLEL);
5502 }
5503 freechain (transchain);
5504 }
5505 }
5506 }
5507
5508 int mbk_checklofig (lofig_list * fig)
5509 {
5510 ht *trans_ht;
5511 int fig_ok = 1;
5512 lotrs_list *tr;
5513
5514 trans_ht = addht (101);
5515
5516 for (tr = fig->LOTRS; tr; tr = tr->NEXT) {
5517 if (gethtitem (trans_ht, tr->TRNAME) == EMPTYHT)
5518 addhtitem (trans_ht, tr->TRNAME, 0);
5519 else {
5520 avt_errmsg(MBK_ERRMSG, "018", AVT_ERROR, fig->NAME, tr->TRNAME);
5521 fig_ok = 0;
5522 break;
5523 }
5524 }
5525
5526 delht (trans_ht);
5527
5528 return fig_ok;
5529 }
5530
5531 char *mbk_putconname(locon_list *lc, char *buf)
5532 {
5533 switch(lc->TYPE)
5534 {
5535 case 'E': strcpy(buf, lc->NAME); break;
5536 case 'T': sprintf(buf, "%s.%s", ((lotrs_list *)lc->ROOT)->TRNAME, lc->NAME); break;
5537 case 'I': sprintf(buf, "%s.%s", ((loins_list *)lc->ROOT)->INSNAME, lc->NAME); break;
5538 default:
5539 sprintf(buf, "?%s", lc->NAME);
5540 }
5541 return buf;
5542 }
5543
5544 int mbk_GetPowerSupply (lofig_list *lofig, float *supply)
5545 {
5546 losig_list *losig;
5547 float alim, alim_max = 0;
5548 int losigalim = 0;
5549
5550 for (losig = lofig->LOSIG; losig; losig = losig->NEXT)
5551 if (getlosigalim (losig, &alim)) {
5552 alim_max = alim_max > alim? alim_max: alim;
5553 losigalim = 1;
5554 }
5555
5556 if (losigalim) *supply = alim_max;
5557
5558 return losigalim;
5559 }
5560
5561 char *mbk_get_subckt_name(lotrs_list *tr)
5562 {
5563 char *subcktname=NULL, *modelname;
5564 ptype_list *ptype;
5565
5566 if(tr->MODINDEX < 0) return NULL;
5567
5568 if (( ptype = getptype ( tr->USER, TRANS_FIGURE )))
5569 subcktname = (char*)ptype->DATA;
5570 else
5571 {
5572 modelname=getlotrsmodel(tr);
5573 subcktname = mcc_getsubckt( MCC_MODELFILE, modelname,
5574 MLO_IS_TRANSN(tr->TYPE)?MCC_NMOS:MCC_PMOS,
5575 MCC_TYPICAL, ((float)tr->LENGTH/SCALE_X)*1.0e-6,
5576 ((float)tr->WIDTH/SCALE_X)*1.0e-6);
5577 }
5578 return subcktname;
5579 }
5580
5581 char *mbk_LosigTestREGEX(losig_list *testlosig, char *refname)
5582 {
5583 chain_list *ptchain;
5584
5585 for (ptchain = testlosig->NAMECHAIN; ptchain; ptchain = ptchain->NEXT) {
5586 if (mbk_TestREGEX((char *)ptchain->DATA, refname)) return (char *)ptchain->DATA;
5587 }
5588 return NULL;
5589 }
5590
5591
5592 static unsigned int mbk_montecarlo_global_seed=0, displayseed=1, mbk_montecarlo_global_seed_saved=0;
5593
5594 unsigned int mbk_get_montecarlo_global_seed(int reset)
5595 {
5596 if (reset) mbk_montecarlo_global_seed=0;
5597 if (mbk_montecarlo_global_seed==0)
5598 {
5599 mbk_montecarlo_global_seed=mbk_get_a_seed();
5600 mbk_montecarlo_global_seed_saved=mbk_montecarlo_global_seed;
5601 displayseed=1;
5602 }
5603 if (displayseed)
5604 {
5605 if (V_BOOL_TAB[ __AVT_ENABLE_STAT ].VALUE)
5606 {
5607 char buf[256];
5608 sprintf(buf, "info:Global monte-carlo seed = %u", mbk_montecarlo_global_seed);
5609 avt_log(-1, 0, "%s\n", &buf[5]);
5610 if (MBK_SOCK!=-1)
5611 mbk_sendmsg( MBK_COM_DATA, buf, strlen(buf)+1);
5612 }
5613 displayseed=0;
5614 }
5615 return mbk_montecarlo_global_seed;
5616 }
5617
5618 void mbk_set_montecarlo_global_seed(unsigned int value)
5619 {
5620 mbk_montecarlo_global_seed=value;
5621 }
5622 void mbk_init_montecarlo_global_seed(unsigned int value)
5623 {
5624 mbk_montecarlo_global_seed=value;
5625 mbk_montecarlo_global_seed_saved=mbk_montecarlo_global_seed;
5626 displayseed=1;
5627 }
5628 unsigned int mbk_get_montecarlo_global_seed_init_saved()
5629 {
5630 return mbk_montecarlo_global_seed_saved;
5631 }
5632
5633 static void mbk_recur_Eval_PrintError(char *var, char *expr, chain_list *cl, char *where)
5634 {
5635 chain_list *ch;
5636 int nb;
5637 char buf[2048];
5638
5639 nb=countchain(cl);
5640
5641 strcpy(buf,"");
5642 for (ch=cl; ch!=NULL; ch=ch->NEXT)
5643 {
5644 if (ch!=cl)
5645 {
5646 if (ch->NEXT==NULL)
5647 strcat(buf,"and ");
5648 else
5649 strcat(buf,", ");
5650 }
5651 strcat(buf,"'");
5652 strcat(buf,(char *)ch->DATA);
5653 strcat(buf,"'");
5654 }
5655
5656 avt_errmsg(MBK_ERRMSG, "052", AVT_ERROR, var, expr, where, nb>0?"s":"", buf, nb>0?"are":"is");
5657 }
5658
5659 int mbk_recur_Eval(eqt_ctx *ctx, ht *allparams, char *name, char *where)
5660 {
5661 char *expr;
5662 chain_list *support;
5663 long l;
5664 double value;
5665 if ((l=gethtitem(allparams, name))!=EMPTYHT)
5666 {
5667 expr=(char *)l;
5668 delhtitem(allparams, name);
5669 support=eqt_GetVariables(ctx, expr, 1);
5670 while (support!=NULL)
5671 {
5672 mbk_recur_Eval(ctx, allparams, (char *)support->DATA, where);
5673 support=delchain(support, support);
5674 }
5675 value=eqt_eval(ctx, expr, EQTFAST);
5676 if (!eqt_resistrue(ctx))
5677 {
5678 support=eqt_GetVariables(ctx, expr, 0);
5679 mbk_recur_Eval_PrintError(name, expr, support, where);
5680 freechain(support);
5681 // avt_errmsg(MBK_ERRMSG, "051", AVT_ERROR, name, expr," : set to 0");
5682 }
5683 else if (!finite(value))
5684 avt_errmsg(MBK_ERRMSG, "051", AVT_ERROR, name, expr," : returned NaN or Inf");
5685 eqt_addvar(ctx, name, value);
5686 return 0;
5687 }
5688
5689 return 1;
5690 }
5691
5692 void mbk_recur_Eval_Start(eqt_ctx *ctx, ht *allparams, char *where)
5693 {
5694 chain_list *cl;
5695 cl=GetAllHTKeys(allparams);
5696 while (cl!=NULL)
5697 {
5698 mbk_recur_Eval(ctx, allparams, (char *)cl->DATA, where);
5699 cl=delchain(cl, cl);
5700 }
5701 }
5702
5703 void mbk_EvalGlobalMonteCarloDistributions(eqt_ctx *ctx)
5704 {
5705 ptype_list *pt;
5706 ht *pht;
5707 chain_list *cl;
5708 unsigned int oldseed;
5709
5710 oldseed=eqt_get_current_srand_seed();
5711 eqt_srand(mbk_get_montecarlo_global_seed(0));
5712 pht=addht(100);
5713 for (pt=MBK_MONTE_DIST; pt!=NULL; pt=pt->NEXT)
5714 addhtitem(pht, (void *)pt->TYPE, (long)pt->DATA);
5715 for (pt=MBK_MONTE_PARAMS; pt!=NULL; pt=pt->NEXT)
5716 addhtitem(pht, (void *)pt->TYPE, (long)pt->DATA);
5717
5718 cl=GetAllHTKeys(pht);
5719 while (cl!=NULL)
5720 {
5721 mbk_recur_Eval(ctx, pht, (char *)cl->DATA, "monte-carlo");
5722 cl=delchain(cl, cl);
5723 }
5724 delht(pht);
5725 eqt_srand(oldseed);
5726 }
5727
5728 void mbk_set_transistor_instance_connector_orientation_info (lofig_list * lf)
5729 {
5730 locon_list *lc, *lc0;
5731 chain_list *cl;
5732 ptype_list *pt;
5733 long flag;
5734
5735 for (lc = lf->LOCON; lc != NULL; lc = lc->NEXT) {
5736 if (lc->DIRECTION == IN)
5737 flag = LOCON_INFORMATION_INPUT;
5738 else if (lc->DIRECTION == OUT || lc->DIRECTION == INOUT || lc->DIRECTION == TRISTATE)
5739 flag = LOCON_INFORMATION_OUTPUT;
5740 else
5741 flag = 0;
5742
5743 if (flag != 0) {
5744 if ((pt = getptype (lc->SIG->USER, LOFIGCHAIN)) != NULL) {
5745 for (cl = (chain_list *) pt->DATA; cl != NULL; cl = cl->NEXT) {
5746 lc0 = (locon_list *) cl->DATA;
5747 if (lc0->TYPE=='I' || (lc0->NAME != MBK_GRID_NAME && lc0->NAME != MBK_BULK_NAME)) {
5748 if ((pt = getptype (lc0->USER, LOCON_INFORMATION)) == NULL)
5749 pt = lc0->USER = addptype (lc0->USER, LOCON_INFORMATION, 0);
5750
5751 if ((long)pt->DATA != 0 && (long)pt->DATA != flag)
5752 printf ("conflicting orientation information on net '%s' in figure '%s'\n",
5753 getsigname (lc->SIG), lf->NAME);
5754 else
5755 pt->DATA = (void *)(long)flag;
5756 }
5757 }
5758 }
5759 }
5760 }
5761 }
5762
5763 #define COL_RESI_NAME 0
5764 #define COL_RESI_VAL 1
5765 #define COL_RESI_NODE 2
5766 #define COL_VCARD_VALUE 3
5767
5768 void mbk_CheckPowerSupplies(lofig_list *lf)
5769 {
5770 ptype_list *pt;
5771 chain_list *p1, *p2, *pt0, *root;
5772 chain_list *cl, *ch;
5773 num_list *nm;
5774 locon_list *lc;
5775 int i=0;
5776 char *name;
5777 losig_list *sig;
5778 lowire_list *lw;
5779 vcardnodeinfo *p1vci, *p2vci;
5780
5781 for (sig=lf->LOSIG; sig; sig=sig->NEXT)
5782 {
5783 if ((pt=getptype(sig->USER, MBK_VCARD_NODES))!=NULL)
5784 {
5785 root=(chain_list *)pt->DATA;
5786 if (root->NEXT!=NULL)
5787 {
5788 rcn_flush_signal(lf, sig );
5789 rcn_refresh_signal( lf, sig );
5790 pt0=dupchainlst(root);
5791 for (p1=pt0; p1; p1=p1->NEXT)
5792 {
5793 for (p2=pt0; p2; p2=p2->NEXT)
5794 {
5795 if (p1!=p2 && p1->DATA!=NULL && p2->DATA!=NULL)
5796 {
5797 long a, nb;
5798 char buf[512];
5799 p1vci=(vcardnodeinfo *)p1->DATA;
5800 p2vci=(vcardnodeinfo *)p2->DATA;
5801 if (p1vci->value!=p2vci->value)
5802 cl=rcn_get_a_r_way(sig, p1vci->rcn, p2vci->rcn);
5803 else
5804 cl=NULL;
5805 if (cl!=NULL)
5806 {
5807 Board *b;
5808 b=Board_CreateBoard();
5809 Board_SetSize(b, COL_RESI_NAME, 20, 'l');
5810 Board_SetSize(b, COL_RESI_VAL, 10, 'r');
5811 Board_SetSize(b, COL_RESI_NODE, 10, 'l');
5812 Board_SetSize(b, COL_VCARD_VALUE, 10, 'l');
5813 Board_NewLine(b);
5814 Board_SetValue(b, COL_RESI_NAME, "Resistor Name");
5815 Board_SetValue(b, COL_RESI_VAL, "Resistor Value");
5816 Board_SetValue(b, COL_RESI_NODE, "Node");
5817 Board_SetValue(b, COL_VCARD_VALUE, "Voltage");
5818 Board_NewSeparation(b);
5819 Board_NewLine(b);
5820 a=p1vci->rcn;
5821 sprintf(buf,"[%ld] %s", a, p1vci->name);
5822 Board_SetValue(b, COL_RESI_NODE, buf);
5823 sprintf(buf,"%gv", p1vci->value);
5824 Board_SetValue(b, COL_VCARD_VALUE, buf);
5825
5826 while (cl!=NULL)
5827 {
5828 lw=(lowire_list *)cl->DATA;
5829 if (lw->NODE1!=a) nb=lw->NODE1; else nb=lw->NODE2;
5830
5831 Board_NewLine(b);
5832
5833 if ((pt=getptype(lw->USER, RESINAME))!=NULL)
5834 Board_SetValue(b, COL_RESI_NAME, (char *)pt->DATA);
5835
5836 if (cl->NEXT==NULL)
5837 {
5838 sprintf(buf,"[%ld] %s", (long)p2vci->rcn, p2vci->name);
5839 Board_SetValue(b, COL_RESI_NODE, buf);
5840 sprintf(buf,"%gv", p2vci->value);
5841 Board_SetValue(b, COL_VCARD_VALUE, buf);
5842 }
5843 else
5844 {
5845 for (ch=root; ch!=NULL && ((vcardnodeinfo *)ch->DATA)->rcn!=nb; ch=ch->NEXT) ;
5846 if (ch!=NULL)
5847 {
5848 name=((vcardnodeinfo *)ch->DATA)->name;
5849 sprintf(buf,"%gv", ((vcardnodeinfo *)ch->DATA)->value);
5850 Board_SetValue(b, COL_VCARD_VALUE, buf);
5851 }
5852 else
5853 name=NULL;
5854 sprintf(buf,"[%ld] %s", nb, name==NULL?"":name);
5855 Board_SetValue(b, COL_RESI_NODE, buf);
5856 }
5857 sprintf(buf,"%.1f", lw->RESI);
5858 Board_SetValue(b, COL_RESI_VAL, buf);
5859 a=nb;
5860 cl=delchain(cl, cl);
5861 }
5862 Board_NewSeparation(b);
5863 avt_log(LOGERROR, 0, "*** Resistive path beetween connector '%s' (%gv) and '%s' (%gv)\n", p1vci->name, p1vci->value, p2vci->name, p2vci->value);
5864 Board_Display_sub(NULL, LOGERROR, 0, b, " ");
5865 Board_FreeBoard(b);
5866
5867 // avt_fprintf(stdout, "\n");
5868 i++;
5869 }
5870 }
5871 }
5872 p1->DATA=NULL;
5873 }
5874 freechain(pt0);
5875 }
5876 }
5877 }
5878 if (i>0)
5879 {
5880 avt_errmsg(MBK_ERRMSG, "072", AVT_ERROR);
5881 }
5882 }