Remove 'inline's causing link failures
[tas-yagle.git] / distrib / sources / yagle / genius / gen_symmetric.c
1
2 #include <string.h>
3 #include <errno.h>
4 #include <stdlib.h>
5 #include MUT_H
6 #include MLO_H
7 #include FCL_H
8 #include MLU_H
9 #include AVT_H
10 #include API_H
11 #include "gen_env.h"
12 #include "gen_execute_VHDL.h"
13 #include "gen_model_utils.h"
14 #include "gen_model_transistor.h"
15 #include "gen_corresp.h"
16 #include "gen_search_utils.h"
17 #include "gen_symmetric.h"
18 #include "gen_optimizations.h"
19 #include "gen_display.h"
20
21 chain_list *PENDING_LOFIG_CHAIN=NULL;
22 HeapAlloc swap_heap;
23 ht *radindexht;
24 char **radtable;
25 int curradindex;
26
27 void SwapHeap_Manage(int mode)
28 {
29 if (mode==0)
30 {
31 radindexht=addht(1500);
32 radtable=(char **)mbkalloc(sizeof(char *)*10000);
33 curradindex=1; // 1 to avoid pnode=0
34 CreateHeap(sizeof(undoswap), 0, &swap_heap);
35 }
36 else
37 {
38 DeleteHeap(&swap_heap);
39 mbkfree(radtable);
40 delht(radindexht);
41 }
42 }
43
44 int getradindex(char *name)
45 {
46 long res;
47 res=gethtitem(radindexht, name);
48 if (res!=EMPTYHT) return (int)res;
49 radtable[curradindex++]=name;
50 addhtitem(radindexht, name, (long)(curradindex-1));
51 return curradindex-1;
52 }
53
54 char *fastradical(locon_list *lc)
55 {
56 Pnode2Radical *r;
57 r=(Pnode2Radical *)&lc->PNODE;
58 if (r->radindex<1 || r->radindex>=curradindex) {/*printf("%s",0x01);*/EXIT(44);}
59 return radtable[r->radindex];
60 }
61
62 int fastindex(locon_list *lc)
63 {
64 Pnode2Radical *r;
65 r=(Pnode2Radical *)&lc->PNODE;
66 return r->index;
67 }
68
69
70 void *AddSwap(locon_list *lc, locon_list *sym)
71 {
72 undoswap *temp;
73 temp=(undoswap *)AddHeapItem(&swap_heap);
74 temp->lc=lc;
75 temp->sym=sym;
76 return temp;
77 }
78
79 void UndoAndDeleteSwap(chain_list *cl)
80 {
81 undoswap *temp=(undoswap *)cl->DATA;
82 SwapLoconWithSym(temp->lc, temp->sym);
83 DelHeapItem(&swap_heap, temp);
84 }
85
86 void JustFreeSwap(void *item)
87 {
88 DelHeapItem(&swap_heap, item);
89 }
90
91 void UpdatePendingLofigChain(locon_list *lc, locon_list *sym)
92 {
93 exchange_pending_con(lc, sym);
94 }
95
96 void PushPendingLofigChain(chain_list *cl)
97 {
98 PENDING_LOFIG_CHAIN=addchain(PENDING_LOFIG_CHAIN, cl);
99 while (cl!=NULL)
100 {
101 add_pending_con((locon_list *)cl->DATA, cl);
102 cl=cl->NEXT;
103 }
104 }
105
106 void PopPendingLofigChain()
107 {
108 chain_list *last=PENDING_LOFIG_CHAIN, *cl;
109 for (cl=(chain_list *)last->DATA; cl!=NULL; cl=cl->NEXT)
110 remove_pending_con((locon_list *)cl->DATA);
111 PENDING_LOFIG_CHAIN=PENDING_LOFIG_CHAIN->NEXT;
112 last->NEXT=NULL;
113 freechain(last);
114 }
115
116
117 SymInfoItem *FindVectorRadicalSymInChain(SymInfoItem *sii, locon_list *lc)
118 {
119 while (sii!=NULL && sii->ConnectorRadical!=vectorradical(lc->NAME)) sii=sii->NEXT;
120 return sii;
121 }
122
123 locon_list *FindALoconPlusIndexInChain(SymInfoItem *ch, locon_list *lc_list, int bit_wanted)
124 {
125 locon_list *sym;
126
127 for (sym=lc_list;sym!=NULL && !(fastradical(sym)==ch->ConnectorRadical && fastindex(sym)==bit_wanted);sym=sym->NEXT) ;
128
129 return sym;
130 }
131
132 SymInfoItem *AreYouMySymmetric(SymInfoItem *ch, locon_list *you/*, locon_list *me*/)
133 {
134 char *temp_name;
135 SymInfoItem *ch1;
136
137 temp_name=fastradical(you);
138
139 for (ch1=ch;ch1!=NULL && ch1->ConnectorRadical!=temp_name;ch1=ch1->NEXT) ;
140
141 return ch1;
142 }
143
144 // zinaps : a commenter
145 void SwapLoconWithSym(locon_list *syms_locon, locon_list *circuit_con)
146 {
147 losig_list *tmpsig;
148 ptype_list *lfc,*user,*top,*top1;
149 mark_list *mark0, *mark1;
150 ptype_list *model_sig_last,*model_sig_last1;
151 int setfixed0=0,setfixed1=0;
152
153 #ifdef ZINAPS_DUMP
154 if (GEN_DEBUG_LEVEL>3)
155 gen_printf(3,"symmetry: for %s Swapping connector signals %s(%s) %s(%s)\n",((loins_list *)circuit_con->ROOT)->INSNAME,syms_locon->NAME,syms_locon->SIG->NAMECHAIN->DATA,circuit_con->NAME,circuit_con->SIG->NAMECHAIN->DATA);
156 #endif
157
158 UpdatePendingLofigChain(circuit_con, syms_locon);
159
160 // it's another than myself, we need to swap the fields
161 tmpsig=syms_locon->SIG; syms_locon->SIG=circuit_con->SIG; circuit_con->SIG=tmpsig;
162 user=syms_locon->USER; syms_locon->USER=circuit_con->USER; circuit_con->USER=user;
163
164 // les LOFIGCHAINs doivent etre updatées
165
166 fastswaplofigchain(syms_locon->SIG, circuit_con, syms_locon, 0);
167 fastswaplofigchain(circuit_con->SIG, syms_locon, circuit_con, 0);
168
169 // fixed tag update
170 if ((lfc=getptype(syms_locon->USER,GEN_FIXED_PTYPE))!=NULL) setfixed0=1;
171 if ((lfc=getptype(circuit_con->USER,GEN_FIXED_PTYPE))!=NULL) setfixed1=1;
172 if (setfixed0 || setfixed1) EXIT(110);
173 if ((setfixed0 && !setfixed1) || (!setfixed0 && setfixed1))
174 {
175 if (setfixed0)
176 {
177 syms_locon->USER=delptype(syms_locon->USER, GEN_FIXED_PTYPE);
178 circuit_con->USER=addptype(circuit_con->USER, GEN_FIXED_PTYPE, circuit_con);
179 }
180 else
181 {
182 circuit_con->USER=delptype(circuit_con->USER, GEN_FIXED_PTYPE);
183 syms_locon->USER=addptype(syms_locon->USER, GEN_FIXED_PTYPE, syms_locon);
184 }
185 }
186
187 // marks update
188 mark0=NULL;
189 if ((lfc=getptype(syms_locon->USER,GEN_LOCON_MARK_PTYPE))!=NULL)
190 {
191 mark0=(mark_list *)lfc->DATA;
192 }
193
194 mark1=NULL;
195 if ((lfc=getptype(circuit_con->USER,GEN_LOCON_MARK_PTYPE))!=NULL)
196 {
197 mark1=(mark_list *)lfc->DATA;
198 }
199 // gen_printf(5,"<%p %p>",mark0, mark1);
200 if (mark0 && mark1)
201 {
202 int type;
203 top=getptype(circuit_con->SIG->USER,GEN_VISITED_PTYPE);
204 top1=getptype(syms_locon->SIG->USER,GEN_VISITED_PTYPE);
205 // gen_printf(5,"(%s %s)",mark0->LOSIG->NAMECHAIN->DATA, mark1->LOSIG->NAMECHAIN->DATA);
206 if (mark0->COUNT>1) EXIT(55);
207 if (mark1->COUNT>1) EXIT(56);
208 for (model_sig_last=(ptype_list*)top->DATA; model_sig_last && model_sig_last->DATA!=mark1; model_sig_last=model_sig_last->NEXT) ;
209 if (model_sig_last==NULL) EXIT(35);
210
211 for (model_sig_last1=(ptype_list*)top1->DATA; model_sig_last1 && model_sig_last1->DATA!=mark0; model_sig_last1=model_sig_last1->NEXT) ;
212 if (model_sig_last1==NULL) EXIT(36);
213
214 // inversement des mark dans les LOSIGs du circuit
215 model_sig_last->DATA=mark0;
216 model_sig_last1->DATA=mark1;
217 type=model_sig_last->TYPE; model_sig_last->TYPE=model_sig_last1->TYPE;model_sig_last1->TYPE=type;
218
219 // remise en place des marks dans les LOCONs
220 top=getptype(circuit_con->USER, GEN_LOCON_MARK_PTYPE);
221 top1=getptype(syms_locon->USER, GEN_LOCON_MARK_PTYPE);
222 if (top->DATA==mark0) EXIT(54);
223 top->DATA=mark0;
224 top1->DATA=mark1;
225
226 type=mark0->VISITED; mark0->VISITED=mark1->VISITED; mark1->VISITED=type;
227 tmpsig=mark0->LOSIG; mark0->LOSIG=mark1->LOSIG; mark1->LOSIG=tmpsig;
228 }
229 else if (mark0 || mark1) EXIT(123);
230
231 // gen_printf(5,"\n");
232 }
233
234 locon_list *FindConWithSym(chain_list *locons, locon_list *me)
235 {
236 locon_list *lc;
237 SymInfoItem *ch;
238 chain_list *cl;
239 SymInfoItem *syms;
240 char *tmp_name;
241 int v_me;
242
243 tmp_name=fastradical(me);
244 for (cl=locons;cl!=NULL;cl=cl->NEXT)
245 {
246 lc=(locon_list *)cl->DATA;
247 syms=GetSymmetricChain(lc);
248
249 if (syms==NULL)
250 {
251 avt_errmsg(GNS_ERRMSG, "115", AVT_FATAL, ((loins_list *)lc->ROOT)->INSNAME,lc->NAME);
252 // fprintf(stderr,"connector %s.%s is in coupled list but has no symetric\n",((loins_list *)lc->ROOT)->INSNAME,lc->NAME);
253 EXIT(2);
254 }
255
256 if (syms->FLAGS!=1)
257 {
258 for (ch=syms;ch!=NULL && ch->ConnectorRadical!=tmp_name;ch=ch->NEXT) ;
259 }
260 else
261 {
262 if ((v_me=fastindex(me))==-1) return NULL;
263
264 for (ch=syms;ch!=NULL;ch=ch->NEXT)
265 {
266 if (ch->ConnectorRadical==tmp_name && fastindex(lc)==v_me) break;
267 }
268 }
269 if (ch!=NULL) return lc;
270 }
271 avt_errmsg(GNS_ERRMSG, "116", AVT_FATAL, lc->NAME);
272 // fprintf(stderr,"no symmetry found for connector %s in coupled connector list (1)\n",lc->NAME);
273 EXIT(2);
274 return NULL; // pour la forme
275 }
276
277 static int COUPLED_VECTOR_MODE;
278
279 chain_list *GrabConnectors(loins_list *li, SymInfoItem *syms, int index)
280 {
281 SymInfoItem *cl;
282 chain_list *found=NULL;
283 locon_list *lc;
284 int hasone=0/*, hasnone=0*/;
285 /*
286 // new
287 for (cl=syms;cl!=NULL; cl=cl->NEXT)
288 if (cl->FLAGS==1) hasone=1;
289 else if (cl->FLAGS==0) hasnone=1;
290 */
291 if (hasone)
292 {
293 COUPLED_VECTOR_MODE=1;
294 for (lc=li->LOCON;lc!=NULL;lc=lc->NEXT)
295 {
296 for (cl=syms;cl!=NULL; cl=cl->NEXT)
297 if (cl->FLAGS!=1 && cl->ConnectorRadical==lc->NAME) break;
298 else if (cl->ConnectorRadical==fastradical(lc)/* && index==fastindex(lc)*/) break;
299
300 if (cl!=NULL)
301 found=addchain(found, lc);
302 }
303 }
304 else
305 {
306 COUPLED_VECTOR_MODE=0;
307 //
308 if (syms->FLAGS!=1)
309 {
310 if (index==-1)
311 {
312 for (lc=li->LOCON;lc!=NULL;lc=lc->NEXT)
313 {
314 for (cl=syms;cl!=NULL && cl->ConnectorRadical!=lc->NAME;cl=cl->NEXT) ; // ne marche pas pour les vecteurs
315 if (cl!=NULL)
316 found=addchain(found, lc);
317 }
318 }
319 else
320 {
321 // printf("grab:");
322 for (lc=li->LOCON;lc!=NULL;lc=lc->NEXT)
323 {
324 for (cl=syms;cl!=NULL && !(cl->ConnectorRadical==fastradical(lc) && index==fastindex(lc));cl=cl->NEXT) ; // ne marche pas pour les vecteurs
325 if (cl!=NULL)
326 {
327 found=addchain(found, lc);
328 // printf(" '%s'",lc->NAME);
329 }
330 }
331 // printf("\n");
332 }
333 }
334 else
335 {
336 avt_errmsg(GNS_ERRMSG, "117", AVT_FATAL);
337 // fprintf(stderr,"coupling won't work with vectors ... yet...\n");
338 EXIT(2);
339 }
340 }
341 return found;
342 }
343
344 chain_list *GrabVectorConnectors(loins_list *li, SymInfoItem *syms, char *radical, int index)
345 {
346 SymInfoItem *cl;
347 chain_list *found=NULL;
348 locon_list *lc;
349 /*
350 if (syms->FLAGS==1)
351 {
352 */
353 for (lc=li->LOCON;lc!=NULL;lc=lc->NEXT)
354 {
355 for (cl=syms; cl!=NULL && !(cl->ConnectorRadical==fastradical(lc) && fastindex(lc)==index); cl=cl->NEXT) ; // ne marche pas pour les vecteurs
356 if (cl!=NULL)
357 found=addchain(found, lc);
358 }
359 /* }
360 else
361 {
362 fprintf(stderr,"implicit coupling won't work with bits\n");
363 EXIT(2);
364 }*/
365 return found;
366 radical = NULL;
367 }
368
369 // check if all the connectors are not fixed
370 int CheckConnectorFreedom(chain_list *cl)
371 {
372 for (;cl!=NULL;cl=cl->NEXT)
373 if (isfixed((locon_list *)cl->DATA)) return 1;
374 return 0;
375 }
376
377 chain_list *BuildCorrespondance(chain_list *me, chain_list *you)
378 {
379 chain_list *cl=NULL;
380 locon_list *found, *lc;
381 chain_list *cp, *testyou=you;
382 for (;me!=NULL && testyou!=NULL;me=me->NEXT,testyou=testyou->NEXT)
383 {
384 lc=(locon_list *)me->DATA;
385 found=FindConWithSym(you, lc);
386 if (found==NULL)
387 {
388 // zinaps : la fonction FindConWithSym fait le exit
389 // cette erreur ne sert donc a rien, mais je la laisse quant meme
390 avt_errmsg(GNS_ERRMSG, "118", AVT_FATAL, lc->NAME);
391 // fprintf(stderr,"can not find coupled connector for '%s'\n",lc->NAME);
392 EXIT(2);
393 }
394 cp=addchain(addchain(NULL,found), lc);
395 cl=addchain(cl,cp);
396 }
397 if (testyou!=NULL)
398 {
399 avt_errmsg(GNS_ERRMSG, "116", AVT_FATAL, ((locon_list *)testyou->DATA)->NAME);
400 // fprintf(stderr,"no symmetry found for connector %s in coupled connector list (2)\n",((locon_list *)testyou->DATA)->NAME);
401 EXIT(2);
402 }
403 return cl;
404 }
405
406 void free_double_chain(chain_list *con_cl)
407 {
408 chain_list *ch;
409 for (ch=con_cl;ch!=NULL;ch=ch->NEXT)
410 {
411 freechain((chain_list *)ch->DATA);
412 }
413 freechain(con_cl);
414 }
415
416 locon_list *FindLoconWithIndex(locon_list *lc, char *radical, int index)
417 {
418
419 while (lc!=NULL && !(fastindex(lc)==index && fastradical(lc)==radical))
420 lc=lc->NEXT;
421 return lc;
422 }
423
424 int CheckForCrossSymmetry(locon_list *lc, SymInfoItem *syms, char *v0, int index0, char *v1, int index1, chain_list **con_cl)
425 {
426 SymInfoItem *ch;
427
428 if (syms->FLAGS==1 && index1!=-1 && index0!=index1)
429 {
430 locon_list *pa, *pb;
431 if (v0!=v1)
432 {
433 gen_printf(3,"symmetry : cross symmetry detected %s(%d) - %s(%d)\n", v0, index1, v1, index0);
434 if ((pa=FindLoconWithIndex(lc, v0, index1))==NULL)
435 {
436 avt_errmsg(GNS_ERRMSG, "119", AVT_FATAL, v0, index1, ((loins_list *)lc->ROOT)->INSNAME);
437 // fprintf(stderr,"Could not find connector '%s(%d)' for instance '%s'\n", v0, index1, ((loins_list *)lc->ROOT)->INSNAME);
438 EXIT(1);
439 }
440 if ((pb=FindLoconWithIndex(lc, v1, index0))==NULL)
441 {
442 avt_errmsg(GNS_ERRMSG, "119", AVT_FATAL, v1, index0, ((loins_list *)lc->ROOT)->INSNAME);
443 // fprintf(stderr,"Could not find connector '%s(%d)' for instance '%s'\n", v1, index0, ((loins_list *)lc->ROOT)->INSNAME);
444 EXIT(1);
445 }
446
447 if (isfixed(pa) || isfixed(pb))
448 {
449 return 0;
450 }
451
452 *con_cl=addchain(*con_cl, addchain(addchain(NULL,pb), pa));
453 }
454
455 // implicit coupling for the other signal in symmetric list
456 for (ch=syms;ch!=NULL;ch=ch->NEXT)
457 {
458 if (strcmp(ch->ConnectorRadical, v0)!=0 &&
459 strcmp(ch->ConnectorRadical, v1)!=0)
460 {
461 gen_printf(3,"symmetry : implicit coupling %s(%d) - %s(%d)\n", ch->ConnectorRadical, index0, ch->ConnectorRadical, index1);
462 if ((pa=FindLoconWithIndex(lc, ch->ConnectorRadical, index1))==NULL)
463 {
464 avt_errmsg(GNS_ERRMSG, "119", AVT_FATAL, ch->ConnectorRadical, index1, ((loins_list *)lc->ROOT)->INSNAME);
465 // fprintf(stderr,"Could not find connector '%s(%d)' for instance '%s'\n", ch->ConnectorRadical, index1, ((loins_list *)lc->ROOT)->INSNAME);
466 EXIT(1);
467 }
468 if ((pb=FindLoconWithIndex(lc, ch->ConnectorRadical, index0))==NULL)
469 {
470 avt_errmsg(GNS_ERRMSG, "119", AVT_FATAL, ch->ConnectorRadical, index0, ((loins_list *)lc->ROOT)->INSNAME);
471 // fprintf(stderr,"Could not find connector '%s(%d)' for instance '%s'\n", ch->ConnectorRadical, index0, ((loins_list *)lc->ROOT)->INSNAME);
472 EXIT(1);
473 }
474
475 if (isfixed(pa) || isfixed(pb))
476 {
477 return 0;
478 }
479
480 *con_cl=addchain(*con_cl, addchain(addchain(NULL,pb), pa));
481 }
482 }
483 }
484 return 1;
485 }
486 #if 0
487 static void bit_swapping(chain_list *bi_list, char *radi, int index0, int index1)
488 {
489 chain_list *cl;
490 chain_list *a0=NULL, *a1=NULL, *b0=NULL, *b1=NULL;
491 void *temp;
492 locon_list *one, *two;
493
494 for (cl=bi_list;cl!=NULL;cl=cl->NEXT)
495 {
496 one=(locon_list *)((chain_list *)cl->DATA)->DATA;
497 two=(locon_list *)((chain_list *)cl->DATA)->NEXT->DATA;
498 if (a0==NULL)
499 {
500 if (fastradical(one)==radi && fastindex(one)==index0)
501 {
502 a0=(chain_list *)cl->DATA; a1=((chain_list *)cl->DATA)->NEXT;
503 }
504 }
505 if (b0==NULL)
506 {
507 if (fastradical(one)==radi && fastindex(one)==index1)
508 {
509 b0=(chain_list *)cl->DATA; b1=((chain_list *)cl->DATA)->NEXT;
510 }
511 }
512 }
513 if (a0==NULL || b0==NULL)
514 {
515 avt_errmsg(GNS_ERRMSG, "004", AVT_FATAL, 191);
516 // avt_error("gns", 1, AVT_ERR, "Internal error\n");
517 EXIT(44);
518 }
519 temp=a0->DATA; a0->DATA=b0->DATA; b0->DATA=temp;
520 // temp=a1->DATA; a1->DATA=b1->DATA; b1->DATA=temp;
521 }
522 #endif
523
524 int TryToSwapWithAConnectorWithTheSameName(locon_list **circuit_c, locon_list *model_con, SymInfoItem *syms, int bit_wanted)
525 {
526 chain_list *con_cl, *cl;
527 SymInfoItem *ch;
528 locon_list *sym, *one, *two;
529 locon_list *circuit_con=*circuit_c;
530 char *tmp_name;
531 int force_swap=0;
532
533 tmp_name=/*vectorradical(*/model_con->NAME/*)*/;
534
535 ch=FindVectorRadicalSymInChain(syms, model_con);
536
537 if (ch==NULL) return 0;
538
539 if (!(fastradical(circuit_con)==model_con->NAME && fastindex(circuit_con)==bit_wanted))
540 {
541 chain_list *circuit_list, *sym_list;
542 SymInfoItem *circuit_list_p, *sym_list_p;
543 // search for the symmetric locon
544
545 gen_printf(3,"symmetry (A): '%s' found instead of '%s(%d)'\n",circuit_con->NAME,model_con->NAME, bit_wanted);
546
547 if (isfixed(circuit_con))
548 {
549 gen_printf(3,"*** fixed *** %s.%s\n",((loins_list *)circuit_con->ROOT)->INSNAME,circuit_con->NAME);
550 return 0;
551 } // can't be moved
552
553 sym=FindALoconPlusIndexInChain(ch, ((loins_list *)circuit_con->ROOT)->LOCON, bit_wanted);
554
555 if (sym==NULL)
556 {
557 // not an error
558 // it simply means that the instance won't match because its
559 // paramaters don't match
560 gen_printf(3,"connector '%s(%d)' not found\n",model_con->NAME,bit_wanted);
561 return 0;
562 }
563 // it's fixed, we can do nothing about the swap
564
565 if (isfixed(sym))
566 {
567 gen_printf(3,"*** fixed2 *** %s.%s",((loins_list *)sym->ROOT)->INSNAME,sym->NAME);
568 return 0;
569 }
570
571 circuit_list_p=GetCoupledChain(circuit_con);
572 sym_list_p=GetCoupledChain(sym);
573 if (!((circuit_list_p==NULL && sym_list_p==NULL) || (sym_list_p!=NULL && circuit_list_p!=NULL)))
574 {
575 avt_errmsg(GNS_ERRMSG, "120", AVT_FATAL, circuit_con->NAME,sym->NAME);
576 // fprintf(stderr,"while swapping %s and %s, one of the connector did not have coupled connector list while the other has\n",circuit_con->NAME,sym->NAME);
577 EXIT(2);
578 }
579
580 if (circuit_list_p!=NULL)// && (fastindex(circuit_con)==-1 || (fastindex(circuit_con)!=-1 && fastradical(circuit_con)!=fastradical(sym))))
581 {
582 // there are coupled connectors
583 circuit_list=GrabConnectors((loins_list *)circuit_con->ROOT, circuit_list_p, fastindex(circuit_con));
584 sym_list=GrabConnectors((loins_list *)circuit_con->ROOT, sym_list_p, fastindex(sym));
585
586 if (CheckConnectorFreedom(circuit_list) || CheckConnectorFreedom(sym_list))
587 {
588 freechain(circuit_list);
589 freechain(sym_list);
590 return 0; // at list one the connectors can't be moved
591 }
592 con_cl=BuildCorrespondance(circuit_list, sym_list);
593 /* if (COUPLED_VECTOR_MODE==1)
594 {
595 bit_swapping(con_cl, fastradical(circuit_con), fastindex(circuit_con), fastindex(sym));
596 force_swap=1;
597 }*/
598 freechain(circuit_list);
599 freechain(sym_list);
600 }
601 else
602 {
603 // we already know that the connectors can be freely moved
604 con_cl=addchain(NULL, addchain(addchain(NULL,sym), circuit_con));
605 }
606
607
608 if (force_swap || CheckForCrossSymmetry(((loins_list *)circuit_con->ROOT)->LOCON, GetSymmetricChain(circuit_con), fastradical(circuit_con), fastindex(circuit_con), fastradical(sym), bit_wanted, &con_cl)!=0)
609 {
610
611 for (cl=con_cl;cl!=NULL;cl=cl->NEXT)
612 {
613 one=(locon_list *)((chain_list *)cl->DATA)->DATA;
614 two=(locon_list *)((chain_list *)cl->DATA)->NEXT->DATA;
615 SwapLoconWithSym(two, one);
616 addswap(two, one);
617 }
618
619 free_double_chain(con_cl);
620
621 *circuit_c=sym;
622 }
623 else
624 {
625 free_double_chain(con_cl);
626 return 0;
627 }
628
629 /* setfixed(sym);
630 printf("0. marked fixed %s.%s(%s)\n",((loins_list *)sym->ROOT)->INSNAME,sym->NAME,sym->SIG->NAMECHAIN->DATA); */
631 }
632
633 return 1;
634 }
635
636 // return the next unfixed symmetric connector
637 // last==NULL => begin of the search
638 locon_list *GetNextSymmetric(locon_list *me, locon_list *last)
639 {
640 locon_list *syms_locon;
641 SymInfoItem *syms, *symsrun;
642
643 syms=GetSymmetricChain(me);
644
645 if (syms==NULL) return NULL;
646 if (last==NULL) last=((loins_list *)me->ROOT)->LOCON; // me->NEXT? pour etre + rapide ???
647 else last=last->NEXT;
648
649 for (syms_locon=last;syms_locon!=NULL;syms_locon=syms_locon->NEXT)
650 {
651 // we look in this locon is a symmetric
652 char *temp_name;
653 int v_you, v_me;
654
655 if (syms_locon!=me)
656 {
657 temp_name=fastradical(syms_locon);
658
659 if (syms->FLAGS!=1)
660 {
661 for (symsrun=syms;symsrun!=NULL;symsrun=symsrun->NEXT)
662 {
663 if (symsrun->ConnectorRadical==temp_name && !isfixed(syms_locon))
664 {
665 gen_printf(3,"symmetry (B): slidingnext, choosing %s(%s) for %s\n",syms_locon->NAME,syms_locon->SIG->NAMECHAIN->DATA,me->NAME);
666 return syms_locon;
667 }
668 }
669 }
670 else
671 {
672 if ((v_me=fastindex(me))==-1) return NULL;
673
674 for (symsrun=syms;symsrun!=NULL;symsrun=symsrun->NEXT)
675 {
676 if ((v_you=fastindex(syms_locon))!=-1 && v_me==v_you)
677 {
678 if (symsrun->ConnectorRadical==temp_name && !isfixed(syms_locon))
679 {
680 gen_printf(3,"symmetry (Bv): slidingnext, choosing %s(%s) for %s\n",syms_locon->NAME,syms_locon->SIG->NAMECHAIN->DATA,me->NAME);
681 return syms_locon;
682 }
683 }
684 }
685 }
686 }
687
688 }
689 return NULL;
690 }
691 // return the next unfixed symmetric connector
692 // last==NULL => begin of the search
693 locon_list *GetNextSymmetric2(locon_list *me, locon_list *last)
694 {
695 locon_list *syms_locon;
696 SymInfoItem *syms, *symsrun;
697
698 syms=GetSymmetricChain(me);
699
700 if (syms==NULL) return NULL;
701 if (last==NULL) last=me->NEXT;// pour etre + rapide ???
702 else last=last->NEXT;
703
704 for (syms_locon=last;syms_locon!=NULL;syms_locon=syms_locon->NEXT)
705 {
706 // we look in this locon is a symmetric
707 char *temp_name;
708 int v_you, v_me;
709
710 temp_name=fastradical(syms_locon);
711
712 if (syms->FLAGS!=1)
713 {
714 for (symsrun=syms;symsrun!=NULL;symsrun=symsrun->NEXT)
715 {
716 if (symsrun->ConnectorRadical==temp_name && !isfixed(syms_locon))
717 {
718 gen_printf(3,"symmetry (B): slidingnext, choosing %s(%s) for %s\n",syms_locon->NAME,syms_locon->SIG->NAMECHAIN->DATA,me->NAME);
719 return syms_locon;
720 }
721 }
722 }
723 else
724 {
725 if ((v_me=fastindex(me))==-1) return NULL;
726
727 for (symsrun=syms;symsrun!=NULL;symsrun=symsrun->NEXT)
728 {
729 if ((v_you=fastindex(syms_locon))!=-1 && v_me==v_you)
730 {
731 if (symsrun->ConnectorRadical==temp_name && !isfixed(syms_locon))
732 {
733 gen_printf(3,"symmetry (B): slidingnext, choosing %s(%s) for %s\n",syms_locon->NAME,syms_locon->SIG->NAMECHAIN->DATA,me->NAME);
734 return syms_locon;
735 }
736 }
737 }
738 }
739 }
740 return NULL;
741 }
742
743 /*
744 Echange deux connections si cela est possible
745 Prend en compte les couplages
746 */
747 int TryToSwapConnectors(locon_list *circuit_con, locon_list *sym)
748 {
749 chain_list *ch, *con_cl;
750 locon_list *one, *two;
751
752 chain_list *circuit_list, *sym_list;
753 SymInfoItem *circuit_list_p, *sym_list_p;
754
755 circuit_list_p=GetCoupledChain(circuit_con);
756 sym_list_p=GetCoupledChain(sym);
757 if (!((circuit_list_p==NULL && sym_list_p==NULL) || (sym_list_p!=NULL && circuit_list_p!=NULL)))
758 {
759 avt_errmsg(GNS_ERRMSG, "120", AVT_FATAL, circuit_con->NAME,sym->NAME);
760 // fprintf(stderr,"while swapping %s and %s, one of the connector did not have coupled connector list while the other has\n",circuit_con->NAME,sym->NAME);
761 EXIT(2);
762 }
763
764 if (circuit_list_p!=NULL)
765 {
766 // there are coupled connectors
767 circuit_list=GrabConnectors((loins_list *)circuit_con->ROOT, circuit_list_p, fastindex(circuit_con));
768 sym_list=GrabConnectors((loins_list *)circuit_con->ROOT, sym_list_p, fastindex(sym));
769
770 if (CheckConnectorFreedom(circuit_list) || CheckConnectorFreedom(sym_list))
771 {
772 freechain(circuit_list);
773 freechain(sym_list);
774 return 0; // at list one the connectors can't be moved
775 }
776
777 con_cl=BuildCorrespondance(circuit_list, sym_list);
778 // were commented ---
779 freechain(circuit_list);
780 freechain(sym_list);
781 // ------------------
782 }
783 else
784 {
785 // we already know that the connectors can be freely moved
786 con_cl=addchain(NULL, addchain(addchain(NULL,sym), circuit_con));
787 }
788
789 if (CheckForCrossSymmetry(((loins_list *)circuit_con->ROOT)->LOCON, GetSymmetricChain(circuit_con), fastradical(circuit_con), fastindex(circuit_con), fastradical(sym), fastindex(sym), &con_cl)!=0)
790 {
791
792 for (ch=con_cl;ch!=NULL;ch=ch->NEXT)
793 {
794 one=(locon_list *)((chain_list *)ch->DATA)->DATA;
795 two=(locon_list *)((chain_list *)ch->DATA)->NEXT->DATA;
796 SwapLoconWithSym(two, one);
797 addswap(two, one);
798 // they won't be moved anymore, except if Backward() is called
799 }
800
801 free_double_chain(con_cl);
802 }
803 else
804 {
805 free_double_chain(con_cl);
806 return 0;
807 }
808
809 /* setfixed(circuit_con);
810 printf("1. marked fixed %s.%s(%s)\n",((loins_list *)circuit_con->ROOT)->INSNAME,circuit_con->NAME,circuit_con->SIG->NAMECHAIN->DATA);
811 */
812 return 1;
813 }
814
815 int FindMarkContaining(locon_list * lc, losig_list *ls)
816 {
817 mark_list *mark;
818 ptype_list *head;
819
820 head=getptype(lc->SIG->USER,GEN_MARK_PTYPE);
821 if (!head) return 0;
822
823 for (mark=(mark_list*)head->DATA; mark; mark=mark->NEXT)
824 {
825 if (mark->LOSIG==ls) break;
826 }
827
828 if (mark!=NULL && mark->COUNT==1) return 1;
829 return 0;
830 }
831
832 int TryToSwapWithAConnectorWithTheSameSignalAndWithOneMark(locon_list *circuit_con, losig_list *ls, mark_list **newmark)
833 {
834 chain_list *con_cl, *cl;
835 locon_list *sym, *one, *two;
836 SymInfoItem *syms, *ch;
837 chain_list *circuit_list, *sym_list;
838 SymInfoItem *circuit_list_p, *sym_list_p;
839 mark_list *cmark, *cmark1;
840
841 // if (isfixed(circuit_con)) { printf("*** fixed *** %s.%s\n",((loins_list *)circuit_con->ROOT)->INSNAME,circuit_con->NAME);} // can't be moved
842 // syms=getptype(circuit_con->USER,GEN_SYM_INFO_PTYPE);
843
844 syms=GetSymmetricChain(circuit_con);
845 if (syms==NULL) return 0;
846
847 for (sym=((loins_list *)circuit_con->ROOT)->LOCON;sym!=NULL;sym=sym->NEXT)
848 {
849 if (sym!=circuit_con)
850 {
851 ch=AreYouMySymmetric(syms, sym/*, circuit_con*/);
852
853 if (ch!=NULL && sym->SIG==ls && !isfixed(sym))
854 {
855 if ((cmark=getloconmark(sym))!=NULL && cmark->COUNT==1) break;
856 }
857 }
858 }
859
860 if (sym==NULL) return 0;
861
862 cmark1=getloconmark(circuit_con);
863
864 if (sym!=NULL)
865 gen_printf(3,"Symmetry (C): found candidate %s %c\n",sym->NAME,isfixed(sym)?'F':'-');
866 /*
867 if ((cmark=getloconmark(sym))!=NULL)
868 gen_printf(3,"mark_cnt_sym= %d\n",cmark->COUNT);
869
870 if ((cmark1=getloconmark(circuit_con))!=NULL)
871 gen_printf(3,"mark_cnt_circuit_con= %d\n",cmark1->COUNT);
872 */
873 circuit_list_p=GetCoupledChain(circuit_con);
874 sym_list_p=GetCoupledChain(sym);
875 if (!((circuit_list_p==NULL && sym_list_p==NULL) || (sym_list_p!=NULL && circuit_list_p!=NULL)))
876 {
877 avt_errmsg(GNS_ERRMSG, "120", AVT_FATAL, circuit_con->NAME,sym->NAME);
878 fprintf(stderr,"while swapping %s and %s, one of the connector did not have coupled connector list when the other has\n",circuit_con->NAME,sym->NAME);
879 EXIT(2);
880 }
881
882 if (circuit_list_p!=NULL)
883 {
884 // there are coupled connectors
885 circuit_list=GrabConnectors((loins_list *)circuit_con->ROOT, circuit_list_p, fastindex(circuit_con));
886 sym_list=GrabConnectors((loins_list *)circuit_con->ROOT, sym_list_p, fastindex(sym));
887
888 if (CheckConnectorFreedom(circuit_list) || CheckConnectorFreedom(sym_list))
889 {
890 freechain(circuit_list);
891 freechain(sym_list);
892 return 0; // at list one the connectors can't be moved
893 }
894 con_cl=BuildCorrespondance(circuit_list, sym_list);
895 freechain(circuit_list);
896 freechain(sym_list);
897 }
898 else
899 {
900 // we already know that the connectors can be freely moved
901 con_cl=addchain(NULL, addchain(addchain(NULL,sym), circuit_con));
902 }
903
904 if (CheckForCrossSymmetry(((loins_list *)circuit_con->ROOT)->LOCON, syms, fastradical(circuit_con), fastindex(circuit_con), fastradical(sym), fastindex(sym), &con_cl)!=0)
905 {
906 for (cl=con_cl;cl!=NULL;cl=cl->NEXT)
907 {
908 one=(locon_list *)((chain_list *)cl->DATA)->DATA;
909 if (isfixed(one)) {free_double_chain(con_cl); gen_printf(3,"no possible symmetry: '%s' is not free\n",ccname(one)); return 0;}
910
911 two=(locon_list *)((chain_list *)cl->DATA)->NEXT->DATA;
912 if (isfixed(one)) {free_double_chain(con_cl); gen_printf(3,"no possible symmetry: '%s' is not free\n",ccname(two)); return 0;}
913 }
914
915 for (cl=con_cl;cl!=NULL;cl=cl->NEXT)
916 {
917 one=(locon_list *)((chain_list *)cl->DATA)->DATA;
918 two=(locon_list *)((chain_list *)cl->DATA)->NEXT->DATA;
919 SwapLoconWithSym(two, one);
920 addswap(two, one);
921 }
922
923 free_double_chain(con_cl);
924 }
925 else
926 {
927 free_double_chain(con_cl);
928 return 0;
929 }
930
931 setfixed(circuit_con);
932
933 gen_printf(4,"2. now fixed %s.%s(%s)\n",((loins_list *)circuit_con->ROOT)->INSNAME,circuit_con->NAME,circuit_con->SIG->NAMECHAIN->DATA);
934 *newmark=cmark1; ///*cmark; //*/getloconmark(sym);
935 return 1;
936 }
937
938 /*
939 Si un connecteur i0.A est connecte' sur un mauvais signal S0
940 relie' a i1.D, s'il existe un connecteur i1.B ayant deja marque'
941 le bon signal S1, on essaie d'echanger les connections de i1.B et i1.D
942 s'ils sont sym
943 */
944 int TryToSwapWithAConnectorWithTheMarkedSignal(locon_list *circuit_con, mark_list *failedmark, locon_list **last, SymInfoItem *syms)
945 {
946 locon_list *lc;
947 SymInfoItem *ch;
948 // char *temp_name;
949
950 if (failedmark==NULL) return 0;
951
952 do
953 {
954 for (lc=(*last)->NEXT;lc!=NULL && lc->SIG!=failedmark->LOSIG; lc=lc->NEXT) ;
955 if (lc!=NULL)
956 {
957 // we've found a locon connected to this signal,
958 // now we checked if it's a sym of the locon
959 *last=lc;
960 if (!isfixed(lc))
961 {
962
963 ch=AreYouMySymmetric(syms, lc/*, circuit_con*/);
964
965 if (ch!=NULL)
966 {
967 // yes there's one, we exchange the connector signals
968 if (TryToSwapConnectors(circuit_con, lc)) return 1;
969 }
970 } else gen_printf(4,"-fixed %s-",lc->NAME);
971 }
972 } while (lc!=NULL);
973 return 0;
974 }
975
976
977 /*
978 Gestion des informations de symmetry et de couplage
979 pour chaque modele
980 Une table de hash permet de retrouver la liste des signaux
981 en couplage et symmetrique a partir de:
982 <nom de modele>.<nom de connecteur>
983 Un systeme de cache est cense' ameliorer les performances :)
984 */
985
986
987 ht *scht;
988 chain_list *myallocs;
989
990 typedef struct biinfo
991 {
992 SymInfoItem *syms, *coupl;
993 int index;
994 } biinfo;
995
996 #define CASHS 4
997 #define MAX_SYMLIST 1024
998
999 biinfo *ALL_SYM_INFO[MAX_SYMLIST];
1000 int CUR_SYM_INDEX;
1001
1002 struct localcash
1003 {
1004 int count;
1005 char *model, *con;
1006 biinfo *info;
1007 } entry[CASHS];
1008
1009 void InitSymmetricAndCoupledInfoMecanism()
1010 {
1011 int i;
1012 scht=addht(1024);
1013 for (i=0;i<CASHS;i++) {entry[i].model=NULL;entry[i].count=0;}
1014 myallocs=NULL;
1015 CUR_SYM_INDEX=1;
1016 }
1017
1018 void RemoveSymmetricAndCoupledInfoMecanism()
1019 {
1020 chain_list *ch;
1021 delht(scht);
1022 for (ch=myallocs;ch!=NULL;ch=ch->NEXT)
1023 {
1024 mbkfree(ch->DATA);
1025 }
1026 freechain(myallocs);
1027 }
1028
1029 static char *getkey(char *a, char *b)
1030 {
1031 int i;
1032 char r[1000];
1033 strcpy(r,a);
1034 for (i=0;r[i]!='\0' && r[i]!='_'; i++) ;
1035 if (r[i]=='_' && r[i+1]>='0' && r[i+1]<='9') r[i]='\0'; // 'toto_5_4' is model 'toto'
1036 strcat(r,".");strcat(r,b);
1037 return namealloc(r);
1038 }
1039
1040 void addcash(char *model, char *con, biinfo *bf)
1041 {
1042 int min=0, i;
1043 static int turn=0;
1044 for (i=1;i<CASHS;i++) if (entry[i].count<entry[min].count) {min=i;}
1045 turn++;
1046 if (turn>1000)
1047 {
1048 turn=0;
1049 for (i=0;i<CASHS;i++) entry[i].count=10;
1050 }
1051 entry[min].count=0;
1052 entry[min].model=model;
1053 entry[min].con=con;
1054 entry[min].info=bf;
1055 }
1056
1057 biinfo *getinfo(char *model, char *con)
1058 {
1059 int i;
1060 char *name;
1061 long item, key;
1062
1063 for (i=0;i<CASHS;i++)
1064 if (entry[i].model==model && entry[i].con==con) {entry[i].count++;return entry[i].info;}
1065
1066 name=getkey(model, con);
1067 key=((long)name>>2);
1068 item=gethtitem(scht, (void *)key);
1069 if (item!=EMPTYHT) {addcash(model, con, (biinfo *)item); return (biinfo *)item;}
1070
1071 return NULL;
1072 }
1073
1074 biinfo *getorcreateinfo(char *model, char *con)
1075 {
1076 biinfo *bf;
1077 char *name;
1078 long key;
1079 if ((bf=getinfo(model,con))!=NULL) { return bf; }
1080 bf=(biinfo *)mbkalloc(sizeof(biinfo));
1081 bf->syms=NULL;
1082 bf->coupl=NULL;
1083 bf->index=CUR_SYM_INDEX;
1084 ALL_SYM_INFO[CUR_SYM_INDEX]=bf;
1085 CUR_SYM_INDEX++;
1086 if (CUR_SYM_INDEX==MAX_SYMLIST)
1087 {
1088
1089 avt_errmsg(GNS_ERRMSG, "121", AVT_FATAL, MAX_SYMLIST);
1090 // fprintf(stderr,"INTERNAL LIMITATION: too much symmetric informations.\n\tActual limit is %d.\n", MAX_SYMLIST);
1091 EXIT(1);
1092 }
1093 myallocs=addchain(myallocs, bf);
1094 name=getkey(model, con);
1095 key=((long)name>>2);
1096 addhtitem(scht, (void *)key, (long)bf);
1097 return bf;
1098 }
1099
1100 void addSymmetricInfo(char *figname, char *conname, SymInfoItem *syms)
1101 {
1102 biinfo *bf;
1103 bf=getorcreateinfo(figname, vectorradical(conname));
1104 if (bf->syms!=NULL) return; //EXIT(112);
1105 bf->syms=syms;
1106 }
1107
1108 void addCoupledInfo(char *figname, char *conname, SymInfoItem *coupl)
1109 {
1110 biinfo *bf;
1111 bf=getorcreateinfo(figname, vectorradical(conname));
1112 if (bf->coupl!=NULL) return; //EXIT(112);
1113 bf->coupl=coupl;
1114 }
1115
1116 SymInfoItem *GetSymmetricChain(locon_list *lc)
1117 {
1118 if (lc->TYPE=='T' || lc->FLAGS==0) return NULL;
1119 return ALL_SYM_INFO[lc->FLAGS]->syms;
1120 }
1121
1122 SymInfoItem *OldFashionGetSymmetricChain(locon_list *lc)
1123 {
1124 biinfo *bf;
1125 bf=getinfo(((loins_list *)lc->ROOT)->FIGNAME, vectorradical(lc->NAME));
1126 if (bf==NULL) return NULL;
1127 return bf->syms;
1128 }
1129
1130 void SetSymmetricChainIndexInLoconFlags(locon_list *lc)
1131 {
1132 biinfo *bf;
1133 if (lc->TYPE=='T') { lc->FLAGS=0; return; }
1134 bf=getinfo(((loins_list *)lc->ROOT)->FIGNAME, vectorradical(lc->NAME));
1135 if (bf==NULL) { lc->FLAGS=0; return; }
1136 lc->FLAGS=bf->index;
1137 }
1138 SymInfoItem *GetCoupledChain(locon_list *lc)
1139 {
1140 if (lc->TYPE=='T'|| lc->FLAGS==0) return NULL;
1141 return ALL_SYM_INFO[lc->FLAGS]->coupl;
1142 }
1143
1144 void AddSymsOfLofig(lofig_list *lf)
1145 {
1146 ptype_list *syms;
1147 chain_list *ch;
1148 locon_list *lc;
1149 SymInfoItem *sii, *mysyms;
1150
1151 // retreive instance model
1152 syms=getptype(lf->USER,GEN_SYM_INFO_PTYPE);
1153 if (syms==NULL) return;
1154
1155 for (lc=lf->LOCON;lc!=NULL;lc=lc->NEXT)
1156 {
1157 mysyms=NULL;
1158 // connector has sims?
1159 for (ch=(chain_list *)syms->DATA;ch!=NULL;ch=ch->NEXT)
1160 {
1161 sii=FindVectorRadicalSymInChain((SymInfoItem *)ch->DATA, lc);
1162 if (sii!=NULL)
1163 {
1164 // found, we add the sims
1165 if (mysyms!=NULL)
1166 {
1167 avt_errmsg(GNS_ERRMSG, "122", AVT_FATAL);
1168 // fprintf(stderr,"AddSymsOfLofig: same signal in different symmetry list\n");
1169 EXIT(1);
1170 }
1171
1172 mysyms=(SymInfoItem *)ch->DATA;
1173 }
1174 }
1175 if (mysyms!=NULL)
1176 {
1177 addSymmetricInfo(lf->NAME, lc->NAME, mysyms);
1178 }
1179 }
1180 }
1181
1182 void AddSymsFlagInLoinsLocon(loins_list *li)
1183 {
1184 locon_list *lc;
1185
1186 for (lc=li->LOCON;lc!=NULL;lc=lc->NEXT)
1187 {
1188 SetSymmetricChainIndexInLoconFlags(lc);
1189 }
1190 }
1191
1192 /****************************************************************************/
1193 /* Add a list of signal names to each connector having coupled connectors */
1194 /****************************************************************************/
1195 void AddCoupledOfLofig(lofig_list *lf)
1196 {
1197 ptype_list *syms;
1198 chain_list *ch;
1199 locon_list *lc;
1200 SymInfoItem *sii, *mysyms;
1201
1202 // retreive instance model
1203 syms=getptype(lf->USER,GEN_COUPLED_INFO_PTYPE);
1204 if (syms==NULL) return;
1205
1206 for (lc=lf->LOCON;lc!=NULL;lc=lc->NEXT)
1207 {
1208 mysyms=NULL;
1209 // connector has sims?
1210 for (ch=(chain_list *)syms->DATA;ch!=NULL;ch=ch->NEXT)
1211 {
1212 for (sii=(SymInfoItem *)ch->DATA;sii!=NULL && sii->ConnectorName!=vectorradical(lc->NAME);sii=sii->NEXT) ;
1213 if (sii!=NULL)
1214 {
1215 // found, we add the sims
1216 if (mysyms!=NULL)
1217 {
1218 avt_errmsg(GNS_ERRMSG, "123", AVT_FATAL);
1219 // fprintf(stderr,"AddCoupledOfLofig: same signal in different coupled list\n");
1220 EXIT(1);
1221 }
1222
1223 mysyms=(SymInfoItem *)ch->DATA;
1224 }
1225 }
1226 if (mysyms!=NULL)
1227 {
1228 addCoupledInfo(lf->NAME, lc->NAME, mysyms);
1229 }
1230 }
1231 }
1232
1233 void AddRadicalInfoInPNODE(loins_list *li)
1234 {
1235 locon_list *lc;
1236 Pnode2Radical *r;
1237
1238 for (lc=li->LOCON; lc!=NULL; lc=lc->NEXT)
1239 {
1240 r=(Pnode2Radical *)&lc->PNODE;
1241 r->radindex=getradindex(vectorradical(lc->NAME));
1242 r->index=vectorindex(lc->NAME);
1243 }
1244 }
1245
1246 void AddRadicalInfoInLOCON(locon_list *lc, int radindex, int index)
1247 {
1248 Pnode2Radical *r;
1249
1250 r=(Pnode2Radical *)&lc->PNODE;
1251 r->radindex=radindex;
1252 r->index=index;
1253 }
1254
1255 void ComputeWeightsForLoinsConnectors(lofig_list *lf)
1256 {
1257 long sp=50+curradindex+100, cc, coupl=1, p;
1258 int index;
1259 loins_list *li;
1260 locon_list *lc, *lc0;
1261 SymInfoItem *si;
1262 chain_list *circuit_list, *cl;
1263 ptype_list *p0;
1264 char *temp0;
1265 if ((GEN_OPTIONS_PACK & GEN_DEBUG_REMAPPING)!=0)
1266 printf("compute weight on %s\n",lf->NAME);
1267
1268 for (li=lf->LOINS; li!=NULL; li=li->NEXT)
1269 {
1270 p=sp;
1271 for (lc=li->LOCON; lc!=NULL; lc=lc->NEXT) lc->FLAGS=0;
1272
1273 if ((p0=getptype (li->USER, GEN_ORIG_LOINS_PTYPE))==NULL)
1274 {
1275 if ((GEN_OPTIONS_PACK & GEN_DEBUG_REMAPPING)!=0)
1276 printf(" (1)%s *%s* %s\n",li->INSNAME,li->FIGNAME, li->FIGNAME);
1277 AddRadicalInfoInPNODE(li);
1278 AddSymsFlagInLoinsLocon(li);
1279 }
1280 else
1281 {
1282 temp0=li->FIGNAME;
1283 li->FIGNAME=((loins_list *)p0->DATA)->FIGNAME;
1284 if ((GEN_OPTIONS_PACK & GEN_DEBUG_REMAPPING)!=0)
1285 printf(" (2)%s *%s* %s\n",li->INSNAME,li->FIGNAME, ((loins_list *)p0->DATA)->FIGNAME);
1286 AddRadicalInfoInPNODE(li);
1287 AddSymsFlagInLoinsLocon(li);
1288 li->FIGNAME=temp0;
1289 }
1290 for (lc=li->LOCON; lc!=NULL; lc=lc->NEXT)
1291 {
1292 si=GetSymmetricChain(lc);
1293 if (si!=NULL)
1294 {
1295 for (index=1;index<CUR_SYM_INDEX && ALL_SYM_INFO[index]->syms!=si; index++) ;
1296 if (index>=CUR_SYM_INDEX) EXIT(124);
1297 cc=50+index;
1298 }
1299 else cc=p++;
1300
1301 lc->USER=addptype(lc->USER, FCL_WEIGHT_PTYPE, (void *)cc);
1302 if ((GEN_OPTIONS_PACK & GEN_DEBUG_REMAPPING)!=0)
1303 printf(" w: %s.%s %ld\n",li->INSNAME,lc->NAME,cc);
1304
1305 if (getptype(lc->USER, FCL_COUPLING_PTYPE)!=NULL) continue;
1306
1307 if (si!=NULL)
1308 {
1309 circuit_list=NULL;
1310 if (si->FLAGS==1)
1311 {
1312 circuit_list=GrabVectorConnectors(li, si, fastradical(lc), fastindex(lc));
1313 }
1314 else
1315 if ((si=GetCoupledChain(lc))!=NULL)
1316 {
1317 circuit_list=GrabConnectors(li, si, fastindex(lc));
1318 }
1319
1320 if (circuit_list!=NULL)
1321 {
1322 for (cl=circuit_list; cl!=NULL; cl=cl->NEXT)
1323 {
1324 lc0=(locon_list *)cl->DATA;
1325
1326 if (getptype(lc->USER, FCL_COUPLING_PTYPE)==NULL)
1327 {
1328 lc0->USER=addptype(lc0->USER, FCL_COUPLING_PTYPE, (void *)coupl);
1329 if ((GEN_OPTIONS_PACK & GEN_DEBUG_REMAPPING)!=0)
1330 printf(" cpl: %s %ld\n",lc0->NAME,coupl);
1331 }
1332 }
1333 freechain(circuit_list);
1334 coupl++;
1335 }
1336 }
1337 }
1338
1339 for (lc=li->LOCON; lc!=NULL; lc=lc->NEXT)
1340 {
1341 lc->FLAGS=(short)(long)getptype(lc->USER, FCL_WEIGHT_PTYPE)->DATA;
1342 lc->USER=delptype(lc->USER, FCL_WEIGHT_PTYPE);
1343 lc->PNODE=NULL;
1344 }
1345 }
1346
1347 }
1348
1349 static int compare_locon(const void *a, const void *b)
1350 {
1351 locon_list *a0=*(locon_list **)a, *b0=*(locon_list **)b;
1352 if (fastindex(a0)<fastindex(b0)) return -1;
1353 else if (fastindex(a0)>fastindex(b0)) return 1;
1354 EXIT(4); // a enlever
1355 return 0;
1356 }
1357
1358 static int compare_losig(const void *a, const void *b)
1359 {
1360 losig_list *a0=*(losig_list **)a, *b0=*(losig_list **)b;
1361 int ia, ib;
1362 ia=vectorindex((char *)a0->NAMECHAIN->DATA);
1363 ib=vectorindex((char *)b0->NAMECHAIN->DATA);
1364 if (ia<ib) return -1;
1365 if (ia>ib) return 1;
1366 return 0;
1367 }
1368
1369 void TrytoArrangeSymmetricConnectors(loins_list *li)
1370 {
1371 locon_list *lc, *next, *end_lc, *run;
1372 int nb, i;
1373 SymInfoItem *si;
1374 locon_list **lcs;
1375 losig_list **lss;
1376 char *sigradical;
1377
1378 for (lc=li->LOCON; lc!=NULL; lc=next)
1379 {
1380 next=lc->NEXT;
1381 if ((si=GetSymmetricChain(lc))==NULL) continue;
1382 for (nb=1, end_lc=lc, run=lc->NEXT;
1383 run!=NULL && fastradical(lc)==fastradical(run)
1384 && GetSymmetricChain(run)==si; nb++, end_lc=run, run=run->NEXT) ;
1385 next=run;
1386 if (nb==1) continue;
1387 lcs=(locon_list **)mbkalloc(nb*sizeof(locon_list *));
1388 lss=(losig_list **)mbkalloc(nb*sizeof(losig_list *));
1389 i=0;
1390 sigradical=vectorradical((char *)lc->SIG->NAMECHAIN->DATA);
1391 do
1392 {
1393 lcs[i]=lc;
1394 lss[i]=lc->SIG;
1395 if (vectorindex((char *)lc->SIG->NAMECHAIN->DATA)==-1
1396 || vectorradical((char *)lc->SIG->NAMECHAIN->DATA)!=sigradical
1397 )
1398 {
1399 break;
1400 }
1401 i++; lc=lc->NEXT;
1402 } while (lc!=next);
1403
1404 if (lc==next)
1405 {
1406 qsort(lcs, nb, sizeof(locon_list *), compare_locon);
1407 qsort(lss, nb, sizeof(losig_list *), compare_losig);
1408
1409 for (i=1; i<nb && vectorindex((char *)lss[i]->NAMECHAIN->DATA)==vectorindex((char *)lss[i-1]->NAMECHAIN->DATA)+1; i++) ;
1410 if (i==nb)
1411 {
1412 for (i=0; i<nb; i++)
1413 {
1414 lcs[i]->SIG=lss[i];
1415 // printf("con %s -> sig %s\n", lcs[i]->NAME, (char *)lss[i]->NAMECHAIN->DATA);
1416 }
1417 // printf("---\n");
1418 }
1419 }
1420 mbkfree(lcs); mbkfree(lss);
1421 }
1422
1423 }
1424
1425 typedef struct symentry
1426 {
1427 struct symentry *next;
1428 int nb;
1429 locon_list **tab;
1430 } symentry;
1431
1432 typedef struct
1433 {
1434 locon_list *lc;
1435 ptype_list *user;
1436 losig_list *ls;
1437 } MatElem;
1438
1439 typedef struct
1440 {
1441 int width, height;
1442 int choice;
1443 MatElem *table;
1444 } SymMat;
1445
1446 chain_list *BuildMatrices(chain_list *groups)
1447 {
1448 chain_list *cl, *ch;
1449 int w, h, i;
1450 symentry *se, *se0;
1451 SymMat *sm;
1452
1453 for (cl=groups, ch=NULL; cl!=NULL; cl=cl->NEXT)
1454 {
1455 se=(symentry *)cl->DATA;
1456 w=se->nb;
1457 for (se0=se, h=0; se0!=NULL && se0->nb==w; se0=se0->next, h++) ;
1458 if (se0!=NULL) EXIT(6);
1459 sm=(SymMat *)mbkalloc(sizeof(SymMat));
1460 sm->width=w; sm->height=h;
1461 sm->table=(MatElem *)mbkalloc(sizeof(MatElem)*w*h);
1462 ch=addchain(ch, sm);
1463
1464 for (se0=se, h=0; se0!=NULL; se0=se0->next, h++)
1465 {
1466 for (i=0; i<sm->width; i++)
1467 {
1468 sm->table[h*sm->width+i].lc=se0->tab[i];
1469 sm->table[h*sm->width+i].ls=se0->tab[i]->SIG;
1470 sm->table[h*sm->width+i].user=se0->tab[i]->USER;
1471 }
1472 mbkfree(se0->tab);
1473 }
1474
1475 for (se0=se; se0!=NULL; se0=se)
1476 {
1477 se=se0->next;
1478 mbkfree(se0);
1479 }
1480 }
1481 freechain(groups);
1482 return ch;
1483 }
1484
1485
1486 chain_list *GetLoinsSymmetryTables(loins_list *li)
1487 {
1488 long l;
1489 int index, count/*, cc=100*/;
1490 locon_list *lc, *lc0;
1491 SymInfoItem *si;
1492 chain_list *circuit_list, *cl;
1493 char *temp0;
1494 ht *groups;
1495 symentry *group_list, *se;
1496
1497 groups=addht(10);
1498
1499
1500 // printf("(1) *%s* %s\n",li->INSNAME, li->FIGNAME);
1501 temp0=li->FIGNAME;
1502 li->FIGNAME=modelradical(li->FIGNAME);
1503 AddRadicalInfoInPNODE(li);
1504 AddSymsFlagInLoinsLocon(li);
1505 li->FIGNAME=temp0;
1506
1507 for (lc=li->LOCON; lc!=NULL; lc=lc->NEXT)
1508 {
1509 if (fastindex(lc)!=-1 && getptype(lc->USER, FCL_WEIGHT_PTYPE)==NULL)
1510 {
1511 si=GetSymmetricChain(lc);
1512 if (si!=NULL)
1513 {
1514 for (index=1;index<CUR_SYM_INDEX && ALL_SYM_INFO[index]->syms!=si; index++) ;
1515 if (index>=CUR_SYM_INDEX) EXIT(124);
1516
1517 if ((l=gethtitem(groups, (void *)(long)index))!=EMPTYHT)
1518 group_list=(symentry *)l;
1519 else
1520 group_list=NULL;
1521
1522 circuit_list=GrabVectorConnectors(li, si, fastradical(lc), fastindex(lc));
1523 /* if (si->FLAGS==1)
1524 {
1525 circuit_list=GrabVectorConnectors(li, si, fastradical(lc), fastindex(lc));
1526 }
1527 else
1528 if ((si=GetCoupledChain(lc))!=NULL)
1529 {
1530 circuit_list=GrabConnectors(li, si, fastindex(lc));
1531 }
1532 else
1533 circuit_list=addchain(NULL, lc);
1534 */
1535 for (cl=circuit_list, count=0; cl!=NULL; cl=cl->NEXT, count++) ;
1536 se=(symentry *)mbkalloc(sizeof(symentry));
1537 se->nb=count;
1538 se->tab=mbkalloc(sizeof(locon_list *)*count);
1539 for (cl=circuit_list, count=0; cl!=NULL; cl=cl->NEXT, count++)
1540 {
1541 lc0=(locon_list *)cl->DATA;
1542 lc0->USER=addptype(lc0->USER, FCL_WEIGHT_PTYPE, NULL);
1543 se->tab[count]=lc0;
1544 }
1545
1546 se->next=group_list;
1547 group_list=se;
1548 addhtitem(groups, (void *)(long)index, (long)group_list);
1549 freechain(circuit_list);
1550 }
1551 }
1552 }
1553
1554 for (lc=li->LOCON; lc!=NULL; lc=lc->NEXT)
1555 {
1556 if (getptype(lc->USER, FCL_WEIGHT_PTYPE)!=NULL)
1557 lc->USER=delptype(lc->USER, FCL_WEIGHT_PTYPE);
1558 lc->PNODE=NULL;
1559 }
1560
1561 // for (lc=li->LOCON, cc=1; lc!=NULL; lc=lc->NEXT, cc++) lc->FLAGS=cc;
1562
1563 cl=GetAllHTElems(groups);
1564 delht(groups);
1565 return cl;
1566 }
1567
1568 static int SORT_INDEX=0;
1569 #define _D_LIMITS 100000
1570
1571 void disp_mat(int w, int h, MatElem *tab)
1572 {
1573 int i, j;
1574 printf("-- start -- w=%d -- h=%d --\n",w,h);
1575 for (j=0;j<_D_LIMITS && j<h;j++)
1576 {
1577 for (i=0;i<_D_LIMITS && i<w;i++)
1578 {
1579 printf("%10s (%10s)",tab[j*w+i].lc->NAME,(char *)tab[j*w+i].lc->SIG->NAMECHAIN->DATA);
1580 }
1581 printf("\n");
1582 }
1583 printf("-- end --\n");
1584 }
1585
1586 static int advanced_compare(char *a, char *b)
1587 {
1588 char *ai=a, *bi=b;
1589 char *aend, *bend;
1590 int av, bv;
1591
1592 while (*ai!='\0' && *bi!='\0')
1593 {
1594 if (*ai>='0' && *ai<='9' && *bi>='0' && *bi<='9')
1595 {
1596 av=strtol(ai, &aend, 10);
1597 bv=strtol(bi, &bend, 10);
1598 if (av<bv) return -1;
1599 else if (av>bv) return 1;
1600 ai=aend;
1601 bi=bend;
1602 }
1603 else
1604 if (*ai<*bi) return -1;
1605 else if (*ai>*bi) return 1;
1606 else ai++, bi++;
1607 }
1608 return strcmp(ai,bi);
1609 }
1610
1611 //#define BRUTE_FORCE
1612 //#define BETTER
1613
1614 static int compare_mat_line(const void *a, const void *b)
1615 {
1616 MatElem *a0=(MatElem *)a, *b0=(MatElem *)b;
1617 locon_list *lca, *lcb;
1618 #ifdef BRUTE_FORCE
1619 lca=a0[SORT_INDEX].lc;
1620 lcb=b0[SORT_INDEX].lc;
1621 // printf("%s - %s\n",(char *)lca->SIG->NAMECHAIN->DATA,(char *)lcb->SIG->NAMECHAIN->DATA);
1622 if (strcmp((char *)lca->SIG->NAMECHAIN->DATA, (char *)lcb->SIG->NAMECHAIN->DATA)<0) return -1;
1623 if (strcmp((char *)lca->SIG->NAMECHAIN->DATA, (char *)lcb->SIG->NAMECHAIN->DATA)>0) return 1;
1624 return 0;
1625 #else
1626 #ifdef BETTER
1627 char *a_rad, *b_rad;
1628 int a_index, b_index;
1629 lca=a0[SORT_INDEX].lc;
1630 lcb=b0[SORT_INDEX].lc;
1631 a_rad=vectorradical((char *)lca->SIG->NAMECHAIN->DATA);
1632 b_rad=vectorradical((char *)lcb->SIG->NAMECHAIN->DATA);
1633 if (strcmp(a_rad, b_rad)<0) return -1;
1634 else if (strcmp(a_rad, b_rad)>0) return 1;
1635 a_index=vectorindex((char *)lca->SIG->NAMECHAIN->DATA);
1636 b_index=vectorindex((char *)lcb->SIG->NAMECHAIN->DATA);
1637 if (a_index<b_index) return -1;
1638 else if (a_index>b_index) return 1;
1639 return 0;
1640 #else
1641 lca=a0[SORT_INDEX].lc;
1642 lcb=b0[SORT_INDEX].lc;
1643 return advanced_compare((char *)lca->SIG->NAMECHAIN->DATA, (char *)lcb->SIG->NAMECHAIN->DATA);
1644 #endif
1645 #endif
1646 }
1647 #if 0
1648 static void swap_locon(locon_list *syms_locon, locon_list *circuit_con)
1649 {
1650 losig_list *tmpsig;
1651 ptype_list *user;
1652
1653 #ifdef ZINAPS_DUMP
1654 // if (GEN_DEBUG_LEVEL>3)
1655 // gen_printf(-1,"sort: for %s Swapping connector %s(%s) %s(%s)\n",((loins_list *)circuit_con->ROOT)->INSNAME,syms_locon->NAME,syms_locon->SIG->NAMECHAIN->DATA,circuit_con->NAME,circuit_con->SIG->NAMECHAIN->DATA);
1656 #endif
1657
1658 tmpsig=syms_locon->SIG; syms_locon->SIG=circuit_con->SIG; circuit_con->SIG=tmpsig;
1659 user=syms_locon->USER; syms_locon->USER=circuit_con->USER; circuit_con->USER=user;
1660
1661 // les LOFIGCHAINs doivent etre updatées
1662
1663 fastswaplofigchain(syms_locon->SIG, circuit_con, syms_locon, 0);
1664 fastswaplofigchain(circuit_con->SIG, syms_locon, circuit_con, 0);
1665
1666 }
1667 #endif
1668
1669 void ArrangeInstanceConnectors(loins_list *li)
1670 {
1671 chain_list *matrices, *cl;
1672 MatElem *duptable;
1673 locon_list *orig;
1674 SymMat *sm;
1675 int i,j;
1676
1677 matrices=BuildMatrices(GetLoinsSymmetryTables(li));
1678
1679 for (cl=matrices; cl!=NULL; cl=cl->NEXT)
1680 {
1681 sm=(SymMat *)cl->DATA;
1682 duptable=(MatElem *)mbkalloc(sm->width*sm->height*sizeof(MatElem));
1683 memcpy(duptable, sm->table, sm->width*sm->height*sizeof(MatElem));
1684
1685 SORT_INDEX=0; // devrait passer par un appel de fonction pour etre determine
1686
1687 if ((GEN_OPTIONS_PACK & GEN_DEBUG_REMAPPING)!=0)
1688 disp_mat(sm->width, sm->height, duptable);
1689
1690 qsort(duptable, sm->height, sm->width*sizeof(MatElem), compare_mat_line);
1691
1692 if ((GEN_OPTIONS_PACK & GEN_DEBUG_REMAPPING)!=0)
1693 disp_mat(sm->width, sm->height, duptable);
1694
1695 for (j=0; j<sm->height; j++)
1696 {
1697 for (i=0; i<sm->width; i++)
1698 {
1699 orig=sm->table[j*sm->width+i].lc;
1700 if (orig!=duptable[j*sm->width+i].lc
1701 && sm->table[j*sm->width+i].ls!=duptable[j*sm->width+i].ls
1702 )
1703 {
1704 // dest=duptable[j*sm->width+i].lc;
1705
1706 orig->SIG=duptable[j*sm->width+i].ls;
1707 orig->USER=duptable[j*sm->width+i].user;
1708 if ((GEN_OPTIONS_PACK & GEN_DEBUG_REMAPPING)!=0)
1709 printf("%s -> %s\n",orig->NAME,(char*) orig->SIG->NAMECHAIN->DATA);
1710 fastswaplofigchain(orig->SIG, duptable[j*sm->width+i].lc, orig, 1);
1711 }
1712 }
1713 }
1714
1715 mbkfree(duptable);
1716 mbkfree(sm->table);
1717 mbkfree(sm);
1718 }
1719
1720 freechain(matrices);
1721 }