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 : mailto:alliance-users@asim.lip6.fr
8 *
9 * This progam is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 */
23
24 /****************************************************************************/
25 /* */
26 /* Chaine de CAO & VLSI Alliance */
27 /* */
28 /* Produit : ring router */
29 /* Fichier : placement.c */
30 /* */
31 /* (c) copyright 1992 Laboratoire MASI equipe CAO & VLSI */
32 /* Tous droits reserves */
33 /* Support : e-mail cao-vlsi@masi.ibp.fr */
34 /* */
35 /* Ecrit par : Olivier Van Hautte le : 01/08/92 */
36 /* Modifie par : Franck Wajsburt le : 9/11/94 */
37 /* */
38 /****************************************************************************/
39
40 /*--------------------------------------------------------------------------------------*/
41 /* RING 15 juillet 92 PLACEMENT.C */
42 /* PHASE 4 */
43 /* */
44 /* Les tableaux tab_plots tab_coeur et la liste des connecteurs speciaux sont remplies. */
45 /*--------------------------------------------------------------------------------------*/
46
47 #include "placement.h"
48 #include "compress.h"
49 #include "distance.h"
50 #include "sesame.h"
51 #include "barre.h"
52
53 /*-----------------------------------------------------------------------------------*/
54 /* Cette procedure initialise les structures de donneees necessaires au barres */
55 /* de plots . Elle prend les connecteurs de plots sur l'aboutement de la figure */
56 /* physique de la barre construite precedemment. Si un connecteur n'existe pas */
57 /* dans le niveau demande, on cree un deport, sera traite ulterieurement. */
58 /*-----------------------------------------------------------------------------------*/
59
remplir_tabplots(BARRE_PLOTS tab_plots[NB_FACES],LST_EQUIPO lst_equipo)60 void remplir_tabplots(BARRE_PLOTS tab_plots[NB_FACES], LST_EQUIPO lst_equipo)
61 {
62 int face, sansdeport = 0, avecdeport = 1;
63 phfig_list * ptfig;
64 phcon_list * liste_con;
65 char niveau = 0;
66 long x, y, xarr, yarr;
67 LST_PSEUDO_CON con;
68
69 for (face = 0; face < NB_FACES; face++) {
70 switch (face) {
71 case NORD:
72 case SUD :
73 niveau = ymetal;
74 break;
75 case EST :
76 case OUEST:
77 niveau = xmetal;
78 break;
79 }
80
81 if (tab_plots[face].width != 0) {
82 ptfig = getphfig(tab_plots[face].nomfig, 'A');
83 liste_con = ptfig->PHCON;
84
85 while (liste_con != NULL) {
86
87 /* --------------------------------------------------------------- */
88 /* 1ere passe, on ne prend que les connecteurs du layer de la face */
89 /* --------------------------------------------------------------- */
90
91 if (liste_con->LAYER == niveau) {
92
93 #ifdef COMMENT
94 /* --------------------------------- */
95 /* ces 3 lignes uniquement pour test */
96 /* --------------------------------- */
97
98 con = existe_conplot_lstequipo(liste_con->NAME, lst_equipo);
99 if ((con != NULL) && (con->nom_con == eq_vdd)) {
100 #endif
101 /* ------------------------- */
102 /* Coordonnees du connecteur */
103 /* ------------------------- */
104
105 x = liste_con->XCON;
106 y = liste_con->YCON;
107
108 /* ------------------------------------------------------------------------ */
109 /* Mise a plat des coordonnees par rapport a l'origine de la barre de plots */
110 /* ------------------------------------------------------------------------ */
111
112 xyflat(&xarr, &yarr, x, y, 0L, 0L, ptfig->XAB1, ptfig->YAB1, ptfig->XAB2,
113 ptfig->YAB2, NOSYM);
114
115 /* ------------------------------------------------------------------------ */
116 /* Ajout du pseudo connecteur dans la liste associee a la face du plot */
117 /* ------------------------------------------------------------------------ */
118
119 ajout_pseudo_con_plot(xarr, yarr, liste_con->WIDTH, liste_con->LAYER, liste_con->NAME,
120 face, sansdeport, tab_plots, lst_equipo);
121
122 #ifdef COMMENT
123 }
124 #endif
125 }
126
127 liste_con = liste_con->NEXT;
128 } /* fin du while parcours des conecteurs physiques */
129
130 /*-------------------------------------------------------------------*/
131 /* 2eme passe : on traite les connecteurs qui n'ont pas le bon layer */
132 /*-------------------------------------------------------------------*/
133
134 liste_con = ptfig->PHCON;
135
136 while (liste_con != NULL) {
137
138 if (liste_con->LAYER != niveau) {
139
140 /* ------------------------- */
141 /* Coordonnees du connecteur */
142 /* ------------------------- */
143
144 con = existe_conplot_lstequipo(liste_con->NAME, lst_equipo);
145
146 if ((con != NULL) && (con->largeur == 0)) /* non traite */ {
147 /* deport a effectuer */
148
149 if (mode_debug)
150 printf("Deport mauvais layer %d connecteur %s\n", (int) niveau, liste_con->NAME);
151 alloue_coord(0L, 0, &(con->deport));
152
153 /* con->deport = (PT_COORDONNEES) mbkalloc ((unsigned int) sizeof(COORDONNEES)); */
154
155 (con->deport)->piste = 1; /* C'est un mauvais layer */
156
157 con->deport->proprio = (void * ) con;
158
159 x = liste_con->XCON;
160 y = liste_con->YCON;
161
162 /* ------------------------------------------------------------------------ */
163 /* Mise a plat des coordonnees par rapport a l'origine de la barre de plots */
164 /* ------------------------------------------------------------------------ */
165
166 xyflat(&xarr, &yarr, x, y, 0L, 0L, ptfig->XAB1, ptfig->YAB1, ptfig->XAB2,
167 ptfig->YAB2, NOSYM);
168
169 /* ------------------------------------------------------------------------ */
170 /* Ajout du pseudo connecteur dans la liste associee a la face du plot */
171 /* ------------------------------------------------------------------------ */
172
173 ajout_pseudo_con_plot(xarr, yarr, liste_con->WIDTH, liste_con->LAYER, liste_con->NAME,
174 face, avecdeport, tab_plots, lst_equipo);
175 } /* fin du 2eme if */
176 } /* fin du 1er if */
177
178 liste_con = liste_con->NEXT;
179 } /* fin du while parcours des conecteurs physiques mauvais layer */
180
181 } /* fin du if */ else
182 tab_plots[face].lst_con = NULL;
183
184 } /* fin du for */
185
186 }
187
188 /*-----------------------------------------------------------------------------------*/
189 /* Cette procedure remplir le tableau de pseudo connecteurs du coeur, en les rangeant*/
190 /* par face et par abscisse, x ou y selon la face horizontale ou verticale */
191 /*-----------------------------------------------------------------------------------*/
192
remplir_tabcoeur(LST_PSEUDO_CON tabcoeur[NB_FACES],COEUR lecoeur,LST_EQUIPO lst_equipo)193 void remplir_tabcoeur(LST_PSEUDO_CON tabcoeur[NB_FACES], COEUR lecoeur, LST_EQUIPO lst_equipo)
194 {
195
196 long x, y, xarr, yarr;
197 phcon_list * liste_con = (lecoeur.coeur_ph)->PHCON;
198 phfig_list * coeurph = lecoeur.coeur_ph;
199 int face;
200
201 /* ----------------------------------- */
202 /* Initialisation du tableau de listes */
203 /* ----------------------------------- */
204
205 for (face = 0; face < NB_FACES; face++)
206 tabcoeur[face] = NULL;
207
208 if (mode_debug)
209 printf("REMplir tabcoeur\n");
210
211 if (liste_con == NULL)
212 ringerreur(ERR_CONCOEUREMPTY, &lecoeur, NULL);
213
214 while (liste_con != NULL) {
215
216 /* ------------------------- */
217 /* Coordonnees du connecteur */
218 /* ------------------------- */
219
220 x = liste_con->XCON;
221 y = liste_con->YCON;
222
223 /* ------------------------------------------------------------ */
224 /* Mise a plat des coordonnees par rapport a l'origine du coeur */
225 /* ------------------------------------------------------------ */
226
227 xyflat(&xarr, &yarr, x, y, lecoeur.coord.xabs, lecoeur.coord.yabs, coeurph->XAB1, coeurph->YAB1, coeurph->XAB2,
228 coeurph->YAB2, lecoeur.rotation);
229
230 /* ---------------------------------------------------------------------- */
231 /* Reorientation eventuelle du connecteur si le coeur a subi une rotation */
232 /* ---------------------------------------------------------------------- */
233
234 face = reorientation_con(liste_con->ORIENT, NOSYM);
235
236 /* ---------------------------------------------------------------------- */
237 /* Ajout du pseudo connecteur dans la liste associee a la face du coeur */
238 /* ---------------------------------------------------------------------- */
239
240 ajout_pseudo_con_coeur(xarr, yarr, liste_con, face, tabcoeur, lst_equipo);
241 liste_con = liste_con->NEXT;
242 }
243
244 }
245
246 /*-----------------------------------------------------------------------------------*/
247
affic_tabcoeur(LST_PSEUDO_CON tabcoeur[NB_FACES])248 void affic_tabcoeur(LST_PSEUDO_CON tabcoeur[NB_FACES])
249 {
250
251 int i;
252
253 for (i = 0; i < NB_FACES; i++) {
254 printf("Affic lst face coeur no %d\n", i);
255 affic_lstcon(tabcoeur[i]);
256 }
257
258 }
259
260 /*-----------------------------------------------------------------------------------*/
261
affic_tabplots(BARRE_PLOTS tabplot[NB_FACES])262 void affic_tabplots(BARRE_PLOTS tabplot[NB_FACES])
263 {
264
265 int i;
266
267 for (i = 0; i < NB_FACES; i++) {
268 printf("Nomfig %s largeur %ld\n", tabplot[i].nomfig, tabplot[i].width);
269 printf("Affic lst face barre de plots no %d\n", i);
270 affic_lstcon(tabplot[i].lst_con);
271 }
272
273 }
274
275 /*-----------------------------------------------------------------------------------*/
276 /* Calcul largeur des barres de plots et faces coeurs */
277 /*-----------------------------------------------------------------------------------*/
278
largeur_ab_plots(BARRE_PLOTS tab_plots[NB_FACES],chain_list * nomplot[NB_FACES],chain_list * liste_plotsph)279 void largeur_ab_plots(BARRE_PLOTS tab_plots[NB_FACES],
280 chain_list *nomplot[NB_FACES], chain_list *liste_plotsph)
281 {
282 int face, first;
283 phfig_list * ptfig;
284 long largeur;
285 chain_list * liste;
286
287 /* --------------------------------------------------------- */
288 /* Initialisations et calcul largeur ab d'une barre de plots */
289 /* --------------------------------------------------------- */
290
291 tab_plots[NORD].nomfig = namealloc(FBARRE_N);
292 tab_plots[NORD].nominst = namealloc(IBARRE_N);
293 tab_plots[SUD].nomfig = namealloc(FBARRE_S);
294 tab_plots[SUD].nominst = namealloc(IBARRE_S);
295 tab_plots[EST].nomfig = namealloc(FBARRE_E);
296 tab_plots[EST].nominst = namealloc(IBARRE_E);
297 tab_plots[OUEST].nomfig = namealloc(FBARRE_O);
298 tab_plots[OUEST].nominst = namealloc(IBARRE_O);
299
300 for (face = 0; face < NB_FACES; face++) {
301 first = 1;
302 tab_plots[face].lst_con = NULL;
303 tab_plots[face].nb_deport = 0;
304
305 liste = nomplot[face];
306
307 largeur = 0;
308
309 while (liste != NULL) {
310 if (mode_debug)
311 printf("figure %s\n", ((loins_list * )liste->DATA)->FIGNAME);
312
313 if ((ptfig = appartient_listeplotsph(((loins_list * )liste->DATA)->FIGNAME, liste_plotsph)) != NULL) {
314 if (first) {
315 first = 0;
316 tab_plots[face].height = ptfig->YAB2 - ptfig->YAB1;
317 }
318
319 largeur += (ptfig->XAB2 - ptfig->XAB1);
320 if (mode_debug)
321 printf("largeur AB %ld plot %s \n", (ptfig->XAB2 - ptfig->XAB1), ((loins_list * )liste->DATA)->FIGNAME);
322 }
323
324 liste = liste->NEXT;
325 }
326
327 tab_plots[face].width = largeur;
328 }
329
330 }
331
332 /*-----------------------------------------------------------------------------------*/
333
fabrique_barre_plots(BARRE_PLOTS tab_plots[NB_FACES],COEUR lecoeur,chain_list * nomplot[NB_FACES],chain_list * liste_plotsph,chain_list * lst_conestouest)334 void fabrique_barre_plots(BARRE_PLOTS tab_plots[NB_FACES], COEUR lecoeur,
335 chain_list *nomplot[NB_FACES], chain_list *liste_plotsph,
336 chain_list *lst_conestouest)
337 {
338 int face, first;
339 long width_coeur, height_coeur, largeur = 0;
340 chain_list * liste;
341 phfig_list *barre, *lastfig;
342 long diff, each, touslesnb, nbplotsface, x, y;
343 long nbplotsvidetot, cptplot, cptplotvide;
344 double nbeachvide;
345 phins_list * firstinst, *lastinst, *lastinst2;
346
347 /* ------------------------------------ */
348 /* Il faudra traiter cas rotation coeur */
349 /* ------------------------------------ */
350
351 width_coeur = lecoeur.width;
352 height_coeur = lecoeur.height;
353
354 largeur_ab_plots(tab_plots, nomplot, liste_plotsph);
355
356 /* ---------------------------------------- */
357 /* Construction des quatres barres de plots */
358 /* ---------------------------------------- */
359
360 for (face = 0; face < NB_FACES; face++) {
361 if (tab_plots[face].width != 0) {
362
363 /* ---------------------- */
364 /* Barre de plots definie */
365 /* ---------------------- */
366
367 switch (face) {
368 case EST:
369 case OUEST:
370 largeur = height_coeur;
371 break;
372 case NORD:
373 case SUD:
374 largeur = width_coeur;
375 break;
376 }
377
378 if (tab_plots[face].width >= largeur) {
379 if (mode_debug)
380 printf("face %d plots abutes simplement\n", face);
381
382 liste = nomplot[face];
383 first = 1;
384
385 definir_fig_ph(tab_plots[face].nomfig);
386
387 while (liste != NULL) {
388 if (first) {
389 first = 0;
390 placer_instph(((loins_list * )liste->DATA)->FIGNAME, ((loins_list * )liste->DATA)->INSNAME,
391 NOSYM, 0L, 0L);
392 } else
393 abouteright_plot_fig(((loins_list * )liste->DATA)->FIGNAME, ((loins_list
394 *)liste->DATA)->INSNAME);
395 liste = liste->NEXT;
396 }
397
398 definir_ab_fig();
399 } else {
400
401 /* -------------------------- */
402 /* barre plot < face du coeur */
403 /* -------------------------- */
404
405 if (mode_debug)
406 printf("Largeur barre < largeur coeur \n");
407
408 nbplotsface = compte_nbplotsface(nomplot[face]);
409 diff = largeur - tab_plots[face].width;
410 nbplotsvidetot = diff / lambda;
411
412 if (nbplotsvidetot < 1) {
413 touslesnb = 1;
414 each = 0;
415 } else {
416
417 /* -------------------------- */
418 /* pas de plots vide a ajoute */
419 /* -------------------------- */
420
421 if (1 != nbplotsface)
422 nbeachvide = nbplotsvidetot / (float) (nbplotsface - 1);
423 else
424 nbeachvide = nbplotsvidetot / (float) nbplotsface;
425 if (nbeachvide >= 1) {
426 touslesnb = 1;
427 each = (long) nbeachvide;
428 } else {
429 touslesnb = (long) ((1 / nbeachvide) + 1);
430 each = 1;
431 }
432 }
433
434 if (mode_debug)
435 printf("On ajoute %ld lambda de fils tous les %ld plots\n", each, touslesnb);
436
437 liste = nomplot[face];
438 cptplot = cptplotvide = 0;
439 first = 1;
440
441 definir_fig_ph(tab_plots[face].nomfig);
442 barre = getphfig(tab_plots[face].nomfig, 'A');
443
444 while (liste != NULL) {
445 if ((NULL != liste) && (0 != cptplot) && (0 == cptplot % touslesnb)) {
446 firstlastinst_barre(barre, &firstinst, &lastinst);
447
448 lastfig = getphfig(lastinst->FIGNAME, 'A');
449
450 x = lastinst->XINS + lastfig->XAB2 - lastfig->XAB1 ;
451 y = lastinst->YINS;
452 cptplot++;
453 cptplotvide++;
454
455 placer_instph(((loins_list * )liste->DATA)->FIGNAME, ((loins_list * )liste->DATA)->INSNAME
456 , NOSYM, (x + each * lambda) / SCALE_X , y / SCALE_X);
457
458 firstlastinst_barre(barre, &firstinst, &lastinst2);
459
460 relier_plots_wire1(lastinst, lastinst2, lst_conestouest);
461
462 liste = liste->NEXT;
463 } else
464 {
465 if (first) {
466 first = 0;
467 placer_instph(((loins_list * )liste->DATA)->FIGNAME, ((loins_list
468 *)liste->DATA)->INSNAME, NOSYM, 0L, 0L);
469 } else
470 abouteright_plot_fig(((loins_list * )liste->DATA)->FIGNAME, ((loins_list
471 *)liste->DATA)->INSNAME);
472 cptplot++;
473 liste = liste->NEXT;
474 }
475 }
476
477 definir_ab_fig();
478
479 /* ---------------------------------------------- */
480 /* mise a jour de la largeur de la barre de plots */
481 /* ---------------------------------------------- */
482
483 tab_plots[face].width += cptplotvide * each * lambda;
484
485 }
486
487 } /* fin du if largeur <> 0 */ else if /* largeur =0 else du 1er if */
488 (mode_debug)
489 printf("barre face %d vide\n", face);
490
491 } /* fin du for */
492
493 /* -------------------------------------------------------------- */
494 /* ON reprend chaque figure de plot et on remonte les connecteurs */
495 /* -------------------------------------------------------------- */
496
497 for (face = 0; face < NB_FACES; face++) {
498 if (tab_plots[face].width != 0) {
499 liste = nomplot[face];
500
501 definir_fig_ph(tab_plots[face].nomfig);
502
503 while (liste != NULL) {
504 if (existe_connecteur_faceplot(((loins_list * )liste->DATA)->FIGNAME, SUD, liste_plotsph))
505 remonter_consud_instph(((loins_list * )liste->DATA)->INSNAME);
506 liste = liste->NEXT;
507 }
508
509 if (mode_debug)
510 sauver_fig_ph();
511 }
512 }
513
514 /* for (face=0; face < NB_FACES; face++) {
515 if (tab_plots[face].largeur != 0) {
516 ptfig = getphfig(tab_plots[face].nomfig,'A');
517 viewphfig(ptfig);
518 }
519 }
520 */
521
522 }
523
524 /*----------------------------------------------------------------------------*/
525 /* Fabrication de la grille primaire a partir des connecteurs du coeur. */
526 /* Verification de la distance des conecteurs entre eux leur largeur et leur */
527 /* niveau */
528 /*----------------------------------------------------------------------------*/
529
fabrique_grille_primaire(LST_PSEUDO_CON tab_coeur[NB_FACES],GRILLE tab_grilles[NB_FACES])530 void fabrique_grille_primaire(LST_PSEUDO_CON tab_coeur[NB_FACES],
531 GRILLE tab_grilles[NB_FACES])
532 {
533 LST_PSEUDO_CON liste;
534 int face;
535 char niveau = 0;
536 long largeurmin = 0, largeurmax;
537
538 if (WVIA_ALU1 > WVIA_ALU2)
539 largeurmax = WVIA_ALU1 * lambda;
540 else
541 largeurmax = WVIA_ALU2 * lambda;
542
543 if (mode_debug)
544 printf("Fabrique grille primaire \n");
545 if (mode_debug)
546 printf("alu1 %d alu2 %d\n", ALU1, ALU2);
547
548 for (face = 0; face < NB_FACES; face++) {
549 liste = tab_coeur[face];
550
551 if (mode_debug)
552 printf("Face %d\n", face);
553
554 /* --------------------------- */
555 /* Initialisation de la grille */
556 /* --------------------------- */
557
558 tab_grilles[face].lst_pas = NULL;
559 tab_grilles[face].lst_deportg = NULL;
560 tab_grilles[face].lst_deportd = NULL;
561
562 switch (face) {
563 case NORD:
564 case SUD :
565 niveau = ymetal;
566 largeurmin = ymetal_width;
567 tab_grilles[face].piste.largeur_pas = pitch;
568 break;
569
570 case EST:
571 case OUEST:
572 niveau = xmetal;
573 largeurmin = xmetal_width;
574 tab_grilles[face].piste.largeur_pas = pitch;
575 break;
576 }
577
578 while (liste != NULL) {
579 if (mode_debug)
580 printf("connecteur %s\n", liste->nom_con);
581 if (mode_debug)
582 printf("width connecteur %ld largeurmin %ld niveau requis %d\n", liste->largeur, largeurmin,
583 (int) niveau);
584
585 if(!isvdd(liste->nom_con) && !isvss(liste->nom_con) && (liste->largeur > largeurmax))
586 ringerreur(ERR_CONLARGEUR, liste, NULL);
587
588 if (liste->layer != niveau) /* deport a effectuer */ {
589 if (mode_debug)
590 printf("Deport mauvais layer %d connecteur %s\n", (int) liste->layer, liste->nom_con);
591 alloue_coord(0L, 0, &(liste->deport));
592
593 (liste->deport)->piste = 1; /* mauvais layer */
594 liste->deport->proprio = (void * ) liste;
595
596 switch (liste->layer) {
597 case ALU1:
598 if (liste->largeur < WMIN_ALU1) /* ringerreur largeur connecteur */
599 ringerreur(ERR_CONLARGEUR, liste, NULL);
600 break;
601 case ALU2:
602 if (liste->largeur < WMIN_ALU2) /* ringerreur largeur connecteur */
603 ringerreur(ERR_CONLARGEUR, liste, NULL);
604
605 break;
606 }
607
608 } else if (liste->largeur < largeurmin) /* ringerreur largeur connecteur */
609 ringerreur(ERR_CONLARGEUR, liste, NULL);
610
611 if (moins_dun_pitch_preccon(liste))
612 ringerreur(ERR_CONDISTANCE, liste, NULL);
613
614 ajout_coordonnees_grille(liste->coord, &(tab_grilles[face].lst_pas), face);
615
616 liste = liste->suiv;
617 } /* fin du while */
618
619 } /* fin du for */
620
621 }
622
623 /*-----------------------------------------------------------------------------*/
624 /* Cette procedure place chaque barre de plots par rapport a la face du coeur. */
625 /* Elle essaye plusieurs positions possibles pour chaque barre calule son cout */
626 /* en nombre de deports et garde la meilleure et la plus centree */
627 /*-----------------------------------------------------------------------------*/
628
place_et_cout_barreplot(LST_PSEUDO_CON tab_coeur[NB_FACES],BARRE_PLOTS tab_plots[NB_FACES],COEUR lecoeur,LST_EQUIPO lst_equipo)629 void place_et_cout_barreplot(LST_PSEUDO_CON tab_coeur[NB_FACES],
630 BARRE_PLOTS tab_plots[NB_FACES], COEUR lecoeur,
631 LST_EQUIPO lst_equipo)
632 {
633
634 int face, gauche, droite, haut, bas, cout, first = 0;
635 long diff, barrexmilieu, barreymilieu, barrexcourant, barreycourant;
636
637 if (mode_debug)
638 printf("PLACE barre plots\n");
639
640 for (face = 0; face < NB_FACES; face++) {
641 if (mode_debug)
642 printf("\n******************** FACE %d *************************\n", face);
643
644 if (tab_plots[face].width != 0) {
645 switch (face) {
646 case NORD:
647 case SUD :
648
649 diff = tab_plots[face].width - lecoeur.width;
650
651 if (mode_debug)
652 printf("diff barre - face coeur %ld\n", diff);
653
654 //if (diff >= 0)
655 barrexmilieu = tab_plots[face].coord.xabs = ((lecoeur.coord.xabs - diff / 2) / SCALE_X) *
656 SCALE_X;
657
658 /* --------------------------------------- */
659 /* Largeur barre de plots >= largeur coeur */
660 /* --------------------------------------- */
661
662 //else
663 //barrexmilieu = tab_plots[face].coord.xabs = ((lecoeur.coord.xabs - diff / 2) / SCALE_X) *
664 // SCALE_X;
665
666 /*---------------------------------------------------------------- */
667 /* Largeur barre de plots < largeur coeur */
668 /* La barre de plots est centree sur le coeur */
669 /* Nb iterations a effectuer en deplacant la barre vers la gauche */
670 /* puis vers la droite, on garde la position la plus centree avec */
671 /* le moins de deports */
672 /*---------------------------------------------------------------- */
673
674 if (mode_debug)
675 printf("face %d debutbarremilieu %ld\n", face, barrexmilieu);
676 first = 1;
677
678 for (gauche = 0; gauche <= (NB_ITERATIONS / 2); gauche++) {
679 barrexcourant = barrexmilieu - (gauche * lambda);
680 if (mode_debug)
681 printf("\tbarrexcourant %ld", barrexcourant);
682 if (conplotalim_dans_coeur(lst_equipo, lecoeur, barrexcourant, face))
683 {
684
685 if (first) {
686 if (mode_debug)
687 printf("first place barre alim sont ok\n");
688 first = 0;
689 tab_plots[face].nb_deport = calcul_nbdeport(tab_plots, tab_coeur,
690 lecoeur, lst_equipo, barrexcourant, face);
691 tab_plots[face].coord.xabs = barrexcourant;
692 }
693 else
694 {
695 if (mode_debug)
696 printf("place barre alim sont ok\n");
697 if ((cout = calcul_nbdeport(tab_plots, tab_coeur, lecoeur, lst_equipo,
698 barrexcourant, face)) < tab_plots[face].nb_deport) {
699 if (mode_debug)
700 printf("Nouveau cout bestg %d barrexcourant %ld\n", cout, barrexcourant);
701 tab_plots[face].nb_deport = cout;
702 tab_plots[face].coord.xabs = barrexcourant;
703 }
704 }
705 }
706 }
707
708 /* ----------------------------------- */
709 /* parcours droit, on repart du milieu */
710 /* ----------------------------------- */
711
712 for (droite = 1; droite <= (NB_ITERATIONS / 2); droite++) {
713 barrexcourant = barrexmilieu + (droite * lambda);
714 if (mode_debug)
715 printf("\tbarrexcourant %ld", barrexcourant);
716 if (conplotalim_dans_coeur(lst_equipo, lecoeur, barrexcourant, face))
717 {
718
719 if (first) {
720 if (mode_debug)
721 printf("first place barre alim sont ok\n");
722 first = 0;
723 tab_plots[face].nb_deport = calcul_nbdeport(tab_plots, tab_coeur,
724 lecoeur, lst_equipo, barrexcourant, face);
725 tab_plots[face].coord.xabs = barrexcourant;
726 }
727 else
728 {
729 if (mode_debug)
730 printf("place barre alim sont ok\n");
731 if ((cout = calcul_nbdeport(tab_plots, tab_coeur, lecoeur, lst_equipo,
732 barrexcourant, face)) < tab_plots[face].nb_deport) {
733 if (mode_debug)
734 printf("Nouveau cout bestd %d barrexcourant %ld\n", cout, barrexcourant);
735 tab_plots[face].nb_deport = cout;
736 tab_plots[face].coord.xabs = barrexcourant;
737 } else
738 if ((cout == tab_plots[face].nb_deport)
739 && (tab_plots[face].coord.xabs <= barrexmilieu)
740 && ((barrexcourant - barrexmilieu) < (barrexmilieu - tab_plots[face].coord.xabs))) {
741
742 /* ------------------------------------------------------------------ */
743 /* test egalite et proximite du milieu */
744 /* vrai si egalite et position retenue precedemment etait a gauche */
745 /* du milieu et si position courante droite est plus proche du milieu */
746 /* que la gauche, on garde la plus centree, uggh ! */
747 /* ------------------------------------------------------------------ */
748
749 if (mode_debug)
750 printf("Nouveau cout bestd centree %d barrexcourant %ld\n", cout, barrexcourant);
751 tab_plots[face].coord.xabs = barrexcourant;
752 }
753 } /* fin du else */
754 }
755 } /* fin du for */
756
757 break; /* Fin Nord Sud */
758
759 case EST :
760 case OUEST:
761
762 diff = tab_plots[face].width - lecoeur.height;
763 if (mode_debug)
764 printf("diff barre - face coeur %ld\n", diff);
765
766 //if (diff >= 0)
767 barreymilieu = tab_plots[face].coord.yabs = ((lecoeur.coord.yabs - diff / 2) / SCALE_X) *
768 SCALE_X;
769
770 /*---------------------------------------- */
771 /* Hauteur barre de plots >= Hauteur coeur */
772 /*---------------------------------------- */
773
774 //else
775 //barreymilieu = tab_plots[face].coord.yabs = ((lecoeur.coord.yabs - diff / 2) / SCALE_X) *
776 // SCALE_X;
777
778 /* ------------------------------------------------------------ */
779 /* Hauteur barre de plots < Hauteur coeur */
780 /* La barre de plots est centree sur le coeur */
781 /* Nb iterations a effectuer en deplacant la barre vers le bas */
782 /* puis vers le haut, on garde la position la plus centree avec */
783 /* le moins de deports */
784 /* ------------------------------------------------------------ */
785
786 if (mode_debug)
787 printf("face %d debutbarremilieu %ld\n", face, barreymilieu);
788
789 first = 1;
790
791 for (bas = 0; bas <= (NB_ITERATIONS / 2); bas++) {
792 barreycourant = barreymilieu - (bas * lambda);
793 if (mode_debug)
794 printf("\tbarreycourant %ld", barreycourant);
795
796 if (conplotalim_dans_coeur(lst_equipo, lecoeur, barreycourant, face))
797 {
798
799 if (first) {
800 if (mode_debug)
801 printf("first place barre alim sont ok\n");
802 first = 0;
803 tab_plots[face].nb_deport = calcul_nbdeport(tab_plots, tab_coeur,
804 lecoeur, lst_equipo, barreycourant, face);
805 tab_plots[face].coord.yabs = barreycourant;
806 }
807 else
808 {
809 if (mode_debug)
810 printf("place barre alim sont ok\n");
811 if ((cout = calcul_nbdeport(tab_plots, tab_coeur, lecoeur, lst_equipo,
812 barreycourant, face)) < tab_plots[face].nb_deport) {
813 if (mode_debug)
814 printf("Nouveau cout bestb %d barreycourant %ld\n", cout, barreycourant);
815 tab_plots[face].nb_deport = cout;
816 tab_plots[face].coord.yabs = barreycourant;
817 }
818 }
819 }
820 }
821
822 /* ---------------------------------- */
823 /* parcours haut, on repart du milieu */
824 /* ---------------------------------- */
825
826 for (haut = 1; haut <= (NB_ITERATIONS / 2); haut++) {
827 barreycourant = barreymilieu + (haut * lambda);
828 if (mode_debug)
829 printf("\tbarreycourant %ld", barreycourant);
830
831 if (conplotalim_dans_coeur(lst_equipo, lecoeur, barreycourant, face))
832 {
833
834 if (first) {
835 if (mode_debug)
836 printf("first place barre alim sont ok\n");
837 first = 0;
838 tab_plots[face].nb_deport = calcul_nbdeport(tab_plots, tab_coeur,
839 lecoeur, lst_equipo, barreycourant, face);
840 tab_plots[face].coord.yabs = barreycourant;
841 }
842 else
843 {
844 if (mode_debug)
845 printf("place barre alim sont ok\n");
846
847 if ((cout = calcul_nbdeport(tab_plots, tab_coeur, lecoeur, lst_equipo,
848 barreycourant, face)) < tab_plots[face].nb_deport) {
849 if (mode_debug)
850 printf("Nouveau cout besth %d barreycourant %ld\n", cout, barreycourant);
851 tab_plots[face].nb_deport = cout;
852 tab_plots[face].coord.yabs = barreycourant;
853 } else
854 if ((cout == tab_plots[face].nb_deport)
855 && (tab_plots[face].coord.yabs <= barreymilieu)
856 && ((barreycourant - barreymilieu) < (barreymilieu - tab_plots[face].coord.yabs))) {
857
858 /* ----------------------------------------------------------------- */
859 /* test egalite et proximite du milieu */
860 /* vrai si egalite et position retenue precedemment etait en bas */
861 /* du milieu et si position courante haute est plus proche du milieu */
862 /* que celle du bas, on garde la plus centree, uggh ! */
863 /* ----------------------------------------------------------------- */
864
865 if (mode_debug)
866 printf("Nouveau cout besth centre %d barreycourant %ld\n", cout, barreycourant);
867 tab_plots[face].coord.yabs = barreycourant;
868 }
869 }
870 }
871 }
872
873 break; /* Fin Est Ouest */
874 } /* Fin du switch */
875
876 if (first)
877 /* ------------------------------------------------------------------------ */
878 /* Ce qui veut dire qu'on a pas pu placer la barre de plot a cause des alim */
879 /* ------------------------------------------------------------------------ */
880 ringerreur(ERR_BARREALIM, (void * ) & face, NULL);
881
882 if (mode_debug)
883 printf("Placement de la barre %d xabs %ld yabs %ld\n", face, tab_plots[face].coord.xabs, tab_plots[face].coord.yabs);
884 } /* Fin du if barre existante */
885
886 } /* Fin du for */
887
888 place_vertical_barreplot(tab_plots, tab_coeur, lecoeur, lst_equipo);
889 }
890
891 /*--------------------------------------------------------------------------------*/
892 /* Placement vertical des barres de plots = maximum des 4 faces. Pour chaque face */
893 /* nb connect coeur + nb connect plot + 2 fois largalim */
894 /*--------------------------------------------------------------------------------*/
895
place_vertical_barreplot(BARRE_PLOTS tab_plots[NB_FACES],LST_PSEUDO_CON tab_coeur[NB_FACES],COEUR lecoeur,LST_EQUIPO lst_equipo)896 void place_vertical_barreplot(BARRE_PLOTS tab_plots[NB_FACES],
897 LST_PSEUDO_CON tab_coeur[NB_FACES], COEUR lecoeur,
898 LST_EQUIPO lst_equipo)
899 {
900 LST_EQUIPO equipo_vdd, equipo_vss;
901 LST_PSEUDO_CON liste;
902 int face;
903 long largvdd, largvss, diff1, diff2, diff;
904
905 long cptcon = 0, maxcoeur = 0, maxplot = 0, largalim, dist;
906
907 recherche_equipo_alim(&equipo_vdd, &equipo_vss, lst_equipo);
908
909 largeur_vddvss(equipo_vdd, equipo_vss, &largvdd, &largvss);
910
911 if (largvdd < largvss)
912 largalim = largvss;
913 else
914 largalim = largvdd;
915
916 for (face = 0; face < NB_FACES; face++) {
917
918 if (tab_plots[face].width != 0) {
919 liste = tab_plots[face].lst_con;
920 cptcon = 0;
921
922 while (liste != NULL) {
923 cptcon++;
924 liste = liste->suiv;
925 }
926 if (cptcon > maxplot)
927 maxplot = cptcon;
928
929 liste = tab_coeur[face];
930 cptcon = 0;
931
932 while (liste != NULL) {
933 cptcon++;
934 liste = liste->suiv;
935 }
936
937 if (cptcon > maxcoeur)
938 maxcoeur = cptcon;
939 }
940 }
941
942 dist = (maxcoeur * pitch + maxplot * pitch + 2 * largalim) * 2;
943
944 for (face = 0; face < NB_FACES; face++)
945 (tab_plots[face].coord).piste = dist / pitch;
946
947 if (tab_plots[NORD].width != 0)
948 (tab_plots[NORD].coord).yabs = (lecoeur.coord).yabs + lecoeur.height + dist;
949 if (tab_plots[SUD].width != 0)
950 (tab_plots[SUD].coord).yabs = (lecoeur.coord).yabs - dist;
951 if (tab_plots[OUEST].width != 0)
952 (tab_plots[OUEST].coord).xabs = (lecoeur.coord).xabs - dist;
953 if (tab_plots[EST].width != 0)
954 (tab_plots[EST].coord).xabs = (lecoeur.coord).xabs + lecoeur.width + dist;
955
956 if (mode_debug)
957 printf("**** nord x%ld y%ld sud x%ld y%ld ouest x%ld y%ld est x%ld y%ld\n", (tab_plots[NORD].coord).xabs,
958 (tab_plots[NORD].coord).yabs, (tab_plots[SUD].coord).xabs, (tab_plots[SUD].coord).yabs, (tab_plots[OUEST].coord).xabs,
959 (tab_plots[OUEST].coord).yabs, (tab_plots[EST].coord).xabs, (tab_plots[EST].coord).yabs);
960
961 /*------------- VERIFICATION DU NON CROISEMEMT DES BARRES MITOYENNES ----------*/
962
963 for (face = 0; face < NB_FACES; face++) {
964 diff1 = diff2 = 0;
965
966 if (0 != tab_plots[face].width)
967 switch (face) {
968 case NORD:
969 if (mode_debug)
970 printf("nord\t");
971 if (0 != tab_plots[EST].width)
972 diff1 = ((lecoeur.coord.yabs + lecoeur.height + tab_plots[NORD].coord.piste * pitch)
973 -(tab_plots[EST].coord.yabs + tab_plots[EST].width));
974 if (0 != tab_plots[OUEST].width)
975 diff2 = ((lecoeur.coord.yabs + lecoeur.height + tab_plots[NORD].coord.piste * pitch)
976 -(tab_plots[OUEST].coord.yabs + tab_plots[OUEST].width));
977
978 if (diff1 < diff2)
979 diff = diff1;
980 else
981 diff = diff2;
982 if (diff < 0)
983 tab_plots[NORD].coord.piste += ((-diff + pitch) / pitch);
984
985 break;
986
987 case SUD:
988 if (mode_debug)
989 printf("sud\t");
990 if (0 != tab_plots[EST].width)
991 diff1 = ( -(lecoeur.coord.yabs - tab_plots[SUD].coord.piste * pitch) + (tab_plots[EST].coord.yabs));
992 if (0 != tab_plots[OUEST].width)
993 diff2 = ( -(lecoeur.coord.yabs - tab_plots[SUD].coord.piste * pitch) + (tab_plots[OUEST].coord.yabs));
994
995 if (diff1 < diff2)
996 diff = diff1;
997 else
998 diff = diff2;
999 if (diff < 0)
1000 tab_plots[SUD].coord.piste += ((-diff + pitch) / pitch);
1001
1002 break;
1003
1004 case EST:
1005 if (mode_debug)
1006 printf("est\t");
1007 if (0 != tab_plots[NORD].width)
1008 diff1 = ((lecoeur.coord.xabs + lecoeur.width + tab_plots[EST].coord.piste * pitch) -
1009 (tab_plots[NORD].coord.xabs + tab_plots[NORD].width));
1010 if (0 != tab_plots[SUD].width)
1011 diff2 = ((lecoeur.coord.xabs + lecoeur.width + tab_plots[EST].coord.piste * pitch) -
1012 (tab_plots[SUD].coord.xabs + tab_plots[SUD].width));
1013
1014 if (diff1 < diff2)
1015 diff = diff1;
1016 else
1017 diff = diff2;
1018 if (diff < 0)
1019 tab_plots[EST].coord.piste += ((-diff + pitch) / pitch);
1020 break;
1021
1022 case OUEST:
1023 if (mode_debug)
1024 printf("ouest\t");
1025 if (0 != tab_plots[NORD].width)
1026 diff1 = (-(lecoeur.coord.xabs - tab_plots[OUEST].coord.piste * pitch ) + (tab_plots[NORD].coord.xabs));
1027
1028 if (0 != tab_plots[SUD].width)
1029 diff2 = (-(lecoeur.coord.xabs - tab_plots[OUEST].coord.piste * pitch ) + (tab_plots[SUD].coord.xabs));
1030
1031 if (diff1 < diff2)
1032 diff = diff1;
1033 else
1034 diff = diff2;
1035 if (diff < 0)
1036 tab_plots[OUEST].coord.piste += ((-diff + pitch) / pitch);
1037 break;
1038 }
1039 } /* fin du for */
1040
1041 if (tab_plots[NORD].width != 0)
1042 (tab_plots[NORD].coord).yabs = tab_plots[NORD].coord.piste * pitch + lecoeur.height;
1043 if (tab_plots[SUD].width != 0)
1044 (tab_plots[SUD].coord).yabs = (lecoeur.coord).yabs - tab_plots[SUD].coord.piste * pitch;
1045 if (tab_plots[OUEST].width != 0)
1046 (tab_plots[OUEST].coord).xabs = (lecoeur.coord).xabs - tab_plots[OUEST].coord.piste * pitch;
1047 if (tab_plots[EST].width != 0)
1048 (tab_plots[EST].coord).xabs = (lecoeur.coord).xabs + lecoeur.width + tab_plots[EST].coord.piste * pitch;
1049
1050 if (mode_debug)
1051 printf("**** nord x%ld y%ld sud x%ld y%ld ouest x%ld y%ld est x%ld y%ld\n", (tab_plots[NORD].coord).xabs,
1052 (tab_plots[NORD].coord).yabs, (tab_plots[SUD].coord).xabs, (tab_plots[SUD].coord).yabs, (tab_plots[OUEST].coord).xabs,
1053 (tab_plots[OUEST].coord).yabs, (tab_plots[EST].coord).xabs, (tab_plots[EST].coord).yabs);
1054
1055 }
1056
1057 /*-----------------------------------------------------------------------------------*/
1058 /* Cette procedure calcule le nombre total de deport de la barre de plot placee */
1059 /* a barrecourant. Cout des alim, connecteurs de plots a deporter, calcul du nombres */
1060 /* de cycles. */
1061 /* nb: la fonction moins_dun_pitch_confacecoeur met a jour la liste des vis a vis */
1062 /*-----------------------------------------------------------------------------------*/
1063
calcul_nbdeport(BARRE_PLOTS tab_plots[NB_FACES],LST_PSEUDO_CON tab_coeur[NB_FACES],COEUR lecoeur,LST_EQUIPO lst_equipo,long barrecourant,int face)1064 int calcul_nbdeport(BARRE_PLOTS tab_plots[NB_FACES],
1065 LST_PSEUDO_CON tab_coeur[NB_FACES], COEUR lecoeur,
1066 LST_EQUIPO lst_equipo, long barrecourant, int face)
1067 {
1068 int nbdepalim = 0, nbdepplots = 0, nbdepcycles = 0, nbdeptotal;
1069 long position;
1070 LST_PSEUDO_CON liste_plots, liste_coeur;
1071 LST_EQUIPO liste_eq;
1072
1073 /* -------------------------------------------------------------------- */
1074 /* Calcul du nombre de deport provoques par l'alim par rapport au pitch */
1075 /* -------------------------------------------------------------------- */
1076
1077 if (mode_debug)
1078 printf("\tCalcul_nbdeport\n");
1079
1080 nbdepalim = calcul_nbdeport_equipo_alim(lst_equipo, barrecourant, face);
1081
1082 liste_eq = lst_equipo;
1083 liste_plots = tab_plots[face].lst_con;
1084 liste_coeur = tab_coeur[face];
1085
1086 /* ----------------------------------------------- */
1087 /* Mise a nulle des listes de vis a vis des equipo */
1088 /* ----------------------------------------------- */
1089
1090 while (liste_eq) {
1091 liste_eq->lst_visavis = NULL; /* prevoir desallocation */
1092 liste_eq = liste_eq->suiv;
1093 }
1094
1095 switch (face) {
1096 case NORD:
1097 case SUD :
1098
1099 while (liste_plots != NULL) {
1100 if (mode_debug)
1101 printf("\t%s\n", liste_plots->nom_con);
1102
1103 if(!isvdd(liste_plots->nom_con) && !isvss(liste_plots->nom_con)) {
1104 position = (liste_plots->coord)->xabs + barrecourant;
1105
1106 if (mode_debug)
1107 printf("position %ld du connecteur %s face %d\n", position, liste_plots->nom_con,
1108 face);
1109
1110 /* --------------------------- */
1111 /* en dehors du coeur = deport */
1112 /* --------------------------- */
1113
1114 if ((position < lecoeur.coord.xabs) || (position > (lecoeur.coord.xabs + lecoeur.width))) {
1115 if (mode_debug)
1116 printf("deport en dehors coeur\t");
1117 nbdepplots++;
1118 } else if (moins_dun_pitch_confacecoeur(position, liste_plots , liste_coeur, lst_equipo,
1119 face)) {
1120 if (mode_debug)
1121 printf("deport - 1 pitch\t");
1122 nbdepplots++;
1123 }
1124
1125 } /* fin du if */
1126
1127 liste_plots = liste_plots->suiv;
1128 } /* fin du while */
1129
1130 break;
1131
1132 case EST :
1133 case OUEST:
1134
1135 while (liste_plots != NULL) {
1136 if (mode_debug)
1137 printf("\t%s\n", liste_plots->nom_con);
1138
1139 if(!isvdd(liste_plots->nom_con) && !isvss(liste_plots->nom_con)) {
1140 position = (liste_plots->coord)->yabs + barrecourant;
1141
1142 if (mode_debug)
1143 printf("position %ld du connecteur %s face %d\n", position, liste_plots->nom_con,
1144 face);
1145
1146 /* --------------------------- */
1147 /* en dehors du coeur = deport */
1148 /* --------------------------- */
1149
1150 if ((position < lecoeur.coord.yabs) || (position > (lecoeur.coord.yabs + lecoeur.height))) {
1151 if (mode_debug)
1152 printf("deport en dehors coeur\t");
1153 nbdepplots++;
1154 } else if (moins_dun_pitch_confacecoeur(position, liste_plots , liste_coeur, lst_equipo,
1155 face)) {
1156 if (mode_debug)
1157 printf("deport - 1 pitch\n");
1158 nbdepplots++;
1159 }
1160
1161 }
1162
1163 liste_plots = liste_plots->suiv;
1164 }
1165
1166 break;
1167 } /* Fin du switch() */
1168
1169 if (mode_debug)
1170 printf("\tNb depplots %d", nbdepplots);
1171
1172 /* --------------------------------------------------------------------------------------------------- */
1173 /* Par la methode deroutage , il n'y aura pas de cycles, donc inutile de calculer les cycles eventuels */
1174 /* nbdepcycles = calcul_nbdeport_cyclesface(lst_equipo); */
1175 /* --------------------------------------------------------------------------------------------------- */
1176
1177 nbdeptotal = nbdepalim + nbdepplots + nbdepcycles;
1178
1179 if (nbdeptotal < 0)
1180 nbdeptotal = 0;
1181
1182 if (mode_debug)
1183 printf("Nombre total de deport %d pour face %d et barrecourant %ld\n", nbdeptotal, face, barrecourant);
1184
1185 return(nbdeptotal);
1186
1187 }
1188
1189 /*------------------------------------------------------------------------------------*/
1190 /* Cette fonction retourne vrai 1 si la position du connecteur plot est a moins d'un */
1191 /* pitch d'un connecteur quelconque du coeur, sinon 0; et mets a jour la liste des */
1192 /* vis a vis des equipo pour calcul ulterieur du nombre de cycle pour la face */
1193 /* Utilisation de la fonction calcul distance entre 2 connecteurs */
1194 /*------------------------------------------------------------------------------------*/
1195
moins_dun_pitch_confacecoeur(long position,LST_PSEUDO_CON plotcon,LST_PSEUDO_CON liste_coeur,LST_EQUIPO lst_equipo,int face)1196 int moins_dun_pitch_confacecoeur(long position, LST_PSEUDO_CON plotcon,
1197 LST_PSEUDO_CON liste_coeur, LST_EQUIPO lst_equipo,
1198 int face)
1199 {
1200 long dist, largcon = 0, largconprec = 0, largeurmin = 0, dminmetalmetal = 0;
1201 long coordcon = 0, coordconprec = 0;
1202
1203 if (liste_coeur == NULL)
1204 return(0); /* pas de connecteurs coeurs donc grille
1205 formee par les con de plots */
1206
1207 switch (face) {
1208 case NORD:
1209 case SUD :
1210 if ((liste_coeur->layer != ymetal) || (plotcon->layer != ymetal)) {
1211 if (ymetal_width < xmetal_width)
1212 largeurmin = ymetal_width;
1213 else
1214 largeurmin = xmetal_width;
1215 /* dminmetalmetal = xmetal_dmin; */
1216 dminmetalmetal = ymetal_dmin;
1217 } else
1218 {
1219 largeurmin = ymetal_width;
1220 dminmetalmetal = ymetal_dmin;
1221 }
1222
1223 while (liste_coeur != NULL) {
1224 dist = distance_con_con(liste_coeur->coord->xabs, 0L, liste_coeur->largeur, liste_coeur->layer, position,
1225 0L, plotcon->largeur, plotcon->layer, face);
1226
1227 if ((liste_coeur->largeur > largeurmin) || (plotcon->largeur > largeurmin)) {
1228
1229 if (mode_debug)
1230 printf("confacecoeur coordcon %ld coordconprec %ld largcon %ld largconprec %ld dist %ld\n",
1231 coordcon,coordconprec,largcon,largconprec,dist);
1232
1233 if (dist < dminmetalmetal) {
1234 ajout_visavis(lst_equipo, liste_coeur, ((plotcon->con_lo)->SIG)->INDEX);
1235 if(!isvdd(plotcon->nom_con) && !isvss(plotcon->nom_con))
1236 return(1);
1237
1238 /* ------------------------------------------------------------- */
1239 /* pas de deport s'il s'agit d'une alim, on continue a parcourir */
1240 /* ------------------------------------------------------------- */
1241 }
1242 } else {
1243 if (dist < pitch) {
1244 if (mode_debug)
1245 printf("visavis posconcoeur %ld position %ld\n", (liste_coeur->coord)->xabs,
1246 position);
1247
1248 ajout_visavis(lst_equipo, liste_coeur, ((plotcon->con_lo)->SIG)->INDEX);
1249 return(1); /* deport a faire */
1250 }
1251 } /* fin du else */
1252
1253 liste_coeur = liste_coeur->suiv;
1254 } /* fin du while */
1255
1256 return(0); /* Pas d'ringerreur c'est lesieur */
1257
1258 break;
1259
1260 case EST :
1261 case OUEST:
1262 if ((liste_coeur->layer != xmetal) || (plotcon->layer != xmetal)) {
1263 if (ymetal_width < xmetal_width)
1264 largeurmin = ymetal_width;
1265 else
1266 largeurmin = xmetal_width;
1267 dminmetalmetal = xmetal_dmin;
1268 } else
1269 {
1270 largeurmin = xmetal_width;
1271 dminmetalmetal = xmetal_dmin;
1272 }
1273
1274 while (liste_coeur != NULL) {
1275 dist = distance_con_con(0L, liste_coeur->coord->yabs, liste_coeur->largeur, liste_coeur->layer, 0L,
1276 position, plotcon->largeur, plotcon->layer, face);
1277
1278 if ((liste_coeur->largeur > largeurmin) || (plotcon->largeur > largeurmin)) {
1279
1280 if (mode_debug)
1281 printf("confacecoeur coordcon %ld coordconprec %ld largcon %ld largconprec %ld dist %ld\n",
1282 coordcon,coordconprec,largcon,largconprec,dist);
1283
1284 if (dist < dminmetalmetal) {
1285 ajout_visavis(lst_equipo, liste_coeur, ((plotcon->con_lo)->SIG)->INDEX);
1286 if(!isvdd(plotcon->nom_con) && !isvss(plotcon->nom_con))
1287 return(1);
1288
1289 /* ------------------------------------------------------------- */
1290 /* pas de deport s'il s'agit d'une alim, on continue a parcourir */
1291 /* ------------------------------------------------------------- */
1292 }
1293 } else {
1294 if (dist < pitch) {
1295 ajout_visavis(lst_equipo, liste_coeur, ((plotcon->con_lo)->SIG)->INDEX);
1296 return(1); /* deport a faire */
1297 }
1298 } /* fin */
1299
1300 liste_coeur = liste_coeur->suiv;
1301 }
1302
1303 return(0); /* Pas d'ringerreur c'est lesieur */
1304 }
1305 return(0);
1306
1307 }
1308
1309 /*--------------------------------------------------------------------------------*/
1310 /* Calcul du nombre de cycles avec la liste des visavis des equipo */
1311 /* Prevoir liberation des ptype liste allouees. */
1312 /*--------------------------------------------------------------------------------*/
1313
calcul_nbdeport_cyclesface(LST_EQUIPO lst_equipo)1314 int calcul_nbdeport_cyclesface(LST_EQUIPO lst_equipo)
1315 {
1316 int nbdeport = 0;
1317 ptype_list * liste;
1318
1319 while (lst_equipo != NULL) {
1320 liste = lst_equipo->lst_visavis;
1321
1322 while (liste != NULL) {
1323 if (existe_visavis(lst_equipo->index, liste->TYPE, lst_equipo)) {
1324 nbdeport++;
1325 }
1326
1327 liste = liste->NEXT;
1328 }
1329 lst_equipo = lst_equipo->suiv;
1330 }
1331
1332 if (mode_debug)
1333 printf("Nb deports cycles trouves %d\n", nbdeport);
1334
1335 return(nbdeport);
1336 }
1337
1338 /*---------------------------------------------------------------------------------*/
1339 /* Calcul du nombre de deports possibles engendres par le placement de la barre */
1340 /*---------------------------------------------------------------------------------*/
1341
calcul_nbdeport_equipo_alim(LST_EQUIPO lst_equipo,long barrecourant,int face)1342 int calcul_nbdeport_equipo_alim(LST_EQUIPO lst_equipo, long barrecourant, int face)
1343 {
1344 LST_EQUIPO equipo_vdd, equipo_vss;
1345 LST_PSEUDO_CON con;
1346 chain_list * ptvdd = NULL , *ptvss = NULL, *ptcour;
1347 int nbdeport = 0, bonus , malus;
1348
1349 recherche_equipo_alim(&equipo_vdd, &equipo_vss, lst_equipo);
1350
1351 ptvdd = equipo_vdd->lst_con;
1352 ptvss = equipo_vss->lst_con;
1353
1354 /* ------------------ */
1355 /* trt des equipo vdd */
1356 /* ------------------ */
1357
1358 if (mode_debug)
1359 printf("trt eq VDD\n");
1360 ptcour = ptvdd;
1361
1362 while (ptcour != NULL) {
1363 con = (LST_PSEUDO_CON) ptcour->DATA;
1364
1365 if ((bonus = croisement_con(ptcour, ptvdd, barrecourant, face)) != 0) {
1366 if (mode_debug)
1367 printf("bonus con %s de %d\n", con->nom_con, bonus);
1368 nbdeport -= (bonus / pitch) ;
1369 }
1370
1371 if ((malus = croisement_con(ptcour, ptvss, barrecourant, face)) != 0) {
1372 if (mode_debug)
1373 printf("malus con %s de %ld\n", con->nom_con, ((vdd_width / pitch) + (vdd_width % pitch)));
1374 nbdeport += ((vdd_width / pitch) + (vdd_width % pitch)) ;
1375 }
1376
1377 ptcour = ptcour->NEXT;
1378 }
1379
1380 /* ------------------ */
1381 /* trt des equipo vss */
1382 /* ------------------ */
1383
1384 ptcour = ptvss;
1385
1386 if (mode_debug)
1387 printf("trt eq VSS\n");
1388
1389 while (ptcour != NULL) {
1390 con = (LST_PSEUDO_CON) ptcour->DATA;
1391
1392 bonus = croisement_con(ptcour, ptvss, barrecourant, face);
1393
1394 if (bonus != 0) {
1395 if (mode_debug)
1396 printf("bonus con %s de %d\n", con->nom_con, bonus);
1397 nbdeport -= (bonus / pitch) ;
1398 }
1399
1400 ptcour = ptcour->NEXT;
1401 }
1402
1403 if (mode_debug)
1404 printf("Nb deports total alim %d \n", nbdeport);
1405
1406 return(nbdeport);
1407 }
1408
1409 /*--------------------------------------------------------------------------------*/
1410 /* Parcours de la liste des connecteurs d'alim pour voir s'il existe des vis */
1411 /* a vis. Si aucun vis a vis retour 0, sinon retour du croisement des 2 */
1412 /* connecteurs */
1413 /*--------------------------------------------------------------------------------*/
1414
croisement_con(chain_list * ptcour,chain_list * ptalim,long barrecourant,int face)1415 int croisement_con(chain_list *ptcour, chain_list *ptalim,
1416 long barrecourant, int face)
1417 {
1418
1419 LST_PSEUDO_CON con, concour;
1420 long position = 0, positioncour = 0, dminmetalmetal = 0, diff = 0;
1421
1422 concour = (LST_PSEUDO_CON) ptcour->DATA;
1423
1424 /*
1425 if (mode_debug)
1426 printf("\tCroisement con %s larg %ld face %d x %ld y %ld\n",concour->nom_con,
1427 concour->largeur,face,(concour->coord)->xabs,(concour->coord)->yabs);
1428 */
1429
1430 switch (face) {
1431 case NORD:
1432 case SUD :
1433 positioncour = (concour->coord)->xabs + barrecourant;
1434 dminmetalmetal = ymetal_dmin;
1435 break;
1436 case EST :
1437 case OUEST:
1438 positioncour = (concour->coord)->yabs + barrecourant;
1439 dminmetalmetal = xmetal_dmin;
1440 break;
1441 }
1442
1443 while (ptalim != NULL) {
1444 con = (LST_PSEUDO_CON) ptalim->DATA;
1445
1446 if ((ptalim != ptcour) && (con->face == face) && (con->coeur_plot != concour->coeur_plot)) {
1447 switch (face) {
1448 case NORD:
1449 case SUD :
1450 position = (con->coord)->xabs + barrecourant;
1451 break;
1452 case EST :
1453 case OUEST:
1454 position = (con->coord)->yabs + barrecourant;
1455 break;
1456 }
1457
1458 /* --------------------------------------- */
1459 /* meme layer car on ne s'en preoccupe pas */
1460 /* --------------------------------------- */
1461
1462 diff = distance_con_con(position, position, con->largeur, con->layer, positioncour, positioncour,
1463 concour->largeur, con->layer, face);
1464
1465 /* diff = position - (con->width / 2) - (con->width % 2)
1466 - (positioncour + (concour->width / 2) + (concour->width % 2));
1467 Avant simplification */
1468
1469 if ((diff < 0) || (diff < dminmetalmetal))
1470 if (mode_debug)
1471 printf("\tposition cour %ld nom %s position %ld ***diffcrois %ld larg %ld\n", positioncour,
1472 con->nom_con, position, diff, con->largeur);
1473
1474 if (diff < 0)
1475 return((int) -diff);
1476 if (diff < dminmetalmetal)
1477 return ((int) pitch);
1478 } /* fin du if */
1479
1480 ptalim = ptalim->NEXT;
1481 }
1482
1483 return((int) 0); /* Aucun croisement trouve */
1484 }
1485
1486 /*-----------------------------------------------------------------------------------*/
1487 /* procedure qui retourne les equipotentielles d'alim */
1488 /*-----------------------------------------------------------------------------------*/
1489
recherche_equipo_alim(LST_EQUIPO * equipo_vdd,LST_EQUIPO * equipo_vss,LST_EQUIPO lst_equipo)1490 void recherche_equipo_alim(LST_EQUIPO *equipo_vdd,
1491 LST_EQUIPO *equipo_vss,
1492 LST_EQUIPO lst_equipo)
1493 {
1494 LST_PSEUDO_CON con;
1495
1496 (*equipo_vdd) = NULL;
1497 (*equipo_vss) = NULL;
1498
1499 while (lst_equipo != NULL) {
1500 con = (LST_PSEUDO_CON) ((lst_equipo->lst_con)->DATA);
1501 if (lst_equipo->type == ALIM) {
1502 con = (LST_PSEUDO_CON) ((lst_equipo->lst_con)->DATA);
1503
1504 if (isvdd(con->nom_con))
1505 (*equipo_vdd) = lst_equipo;
1506 else
1507 (*equipo_vss) = lst_equipo;
1508
1509 if (((*equipo_vss) != NULL) && ((*equipo_vdd) != NULL))
1510 break;
1511 }
1512 lst_equipo = lst_equipo->suiv;
1513 }
1514
1515 if (((*equipo_vss) == NULL) || ((*equipo_vdd) == NULL))
1516 ringerreur(ERR_MANQUEALIM, NULL, NULL);
1517 }
1518
1519 /*-----------------------------------------------------------------------------------*/
1520 /* Verification si les connecteurs d'alim sont dans la face du coeur */
1521 /*-----------------------------------------------------------------------------------*/
1522
conplotalim_dans_coeur(LST_EQUIPO lst_equipo,COEUR coeur,long barrecourant,int face)1523 int conplotalim_dans_coeur(LST_EQUIPO lst_equipo, COEUR coeur,
1524 long barrecourant, int face)
1525 {
1526 LST_EQUIPO equipo_vdd, equipo_vss;
1527 LST_PSEUDO_CON con;
1528 chain_list * liste_vdd;
1529 chain_list * liste_vss;
1530 long alasoupe;
1531
1532 recherche_equipo_alim(&equipo_vdd, &equipo_vss, lst_equipo);
1533
1534 liste_vdd = equipo_vdd->lst_con;
1535 liste_vss = equipo_vss->lst_con;
1536
1537 if (mode_debug)
1538 printf("barrecourant %ld coeurheight %ld coeurwidth %ld\n", barrecourant, coeur.height, coeur.width);
1539
1540 while (liste_vdd != NULL) {
1541 con = (LST_PSEUDO_CON) liste_vdd->DATA;
1542 if ((con->coeur_plot == PLOT_CON) && (con->face == face))
1543
1544 switch (con->face) {
1545 case NORD:
1546 case SUD :
1547 if (((barrecourant + con->coord->xabs - con->largeur / 2) < (coeur.coord).xabs) || ((barrecourant +
1548 con->coord->xabs + con->largeur / 2) > ((coeur.coord).xabs + coeur.width)))
1549 return(0); /* le connecteur n'est pas en face du coeur */
1550
1551 break;
1552
1553 case EST :
1554 case OUEST:
1555 alasoupe = ((barrecourant + con->coord->yabs - con->largeur / 2));
1556 if (mode_debug)
1557 printf("binf %ld\t", alasoupe);
1558 alasoupe = ((barrecourant + con->coord->yabs + con->largeur / 2));
1559 if (mode_debug)
1560 printf("bsup %ld\t", alasoupe);
1561
1562 if (mode_debug)
1563 printf("plot %s coord x %ld y %ld larg %ld\n", con->nom_con, con->coord->xabs, con->coord->yabs,
1564 con->largeur);
1565 if (((barrecourant + con->coord->yabs - con->largeur / 2) < (coeur.coord).yabs) || ((barrecourant +
1566 con->coord->yabs + con->largeur / 2) > ((coeur.coord).yabs + coeur.height)))
1567 return(0); /* le connecteur n'est pas en face du coeur */
1568
1569 break;
1570 }
1571 liste_vdd = liste_vdd->NEXT;
1572 }
1573
1574 while (liste_vss != NULL) {
1575 con = (LST_PSEUDO_CON) liste_vss->DATA;
1576 if ((con->coeur_plot == PLOT_CON) && (con->face == face))
1577
1578 switch (con->face) {
1579 case NORD:
1580 case SUD :
1581 if (((barrecourant + con->coord->xabs - con->largeur / 2) < (coeur.coord).xabs) || ((barrecourant +
1582 con->coord->xabs + con->largeur / 2) > ((coeur.coord).xabs + coeur.width)))
1583 return(0); /* le connecteur n'est pas en face du coeur */
1584
1585 break;
1586
1587 case EST :
1588 case OUEST:
1589 alasoupe = ((barrecourant + con->coord->yabs - con->largeur / 2));
1590 if (mode_debug)
1591 printf("binf %ld\t", alasoupe);
1592 alasoupe = ((barrecourant + con->coord->yabs + con->largeur / 2));
1593 if (mode_debug)
1594 printf("bsup %ld\t", alasoupe);
1595
1596 if (mode_debug)
1597 printf("plot %s coord x %ld y %ld larg %ld\n", con->nom_con, con->coord->xabs, con->coord->yabs,
1598 con->largeur);
1599 if (((barrecourant + con->coord->yabs - con->largeur / 2) < (coeur.coord).yabs) || ((barrecourant +
1600 con->coord->yabs + con->largeur / 2) > ((coeur.coord).yabs + coeur.height)))
1601 return(0); /* le connecteur n'est pas en face du coeur */
1602
1603 break;
1604 }
1605 liste_vss = liste_vss->NEXT;
1606 }
1607
1608 /* ningun problema */
1609 return(1);
1610
1611 }
1612
1613 /*--------------------------------------------------------------------------------*/
1614 /* Apres le placement de la barre de plots, on mets a jour les coordonnes des */
1615 /* connecteurs */
1616 /*--------------------------------------------------------------------------------*/
1617
maj_coordplots(BARRE_PLOTS tab_plots[NB_FACES],LST_EQUIPO lst_equipo)1618 void maj_coordplots(BARRE_PLOTS tab_plots[NB_FACES], LST_EQUIPO lst_equipo)
1619 {
1620 LST_EQUIPO liste_eq = lst_equipo;
1621 LST_PSEUDO_CON liste;
1622 int face;
1623 //char niveau;
1624 long position, /*largeurmin,*/ largeurmax;
1625
1626 if (WVIA_ALU1 > WVIA_ALU2)
1627 largeurmax = WVIA_ALU1 * lambda;
1628 else
1629 largeurmax = WVIA_ALU2 * lambda;
1630
1631 if (mode_debug)
1632 printf("Largeurmax = %ld\n", largeurmax);
1633
1634 /* ----------------------------------------------- */
1635 /* Mise a nulle des listes de vis a vis des equipo */
1636 /* ----------------------------------------------- */
1637
1638 while (liste_eq) {
1639 liste_eq->lst_visavis = NULL; /* prevoir desallocation */
1640 liste_eq = liste_eq->suiv;
1641 }
1642
1643 for (face = 0; face < NB_FACES; face++) {
1644 liste = tab_plots[face].lst_con;
1645
1646 if (mode_debug)
1647 printf("Face %d\n", face);
1648
1649 switch (face) {
1650
1651 case NORD:
1652 case SUD :
1653 //niveau = ymetal;
1654 //largeurmin = ymetal_width;
1655
1656 while (liste != NULL) {
1657 if (mode_debug)
1658 printf("\t%s width = %ld\n", liste->nom_con, liste->largeur);
1659
1660 if(!isvdd(liste->nom_con) && !isvss(liste->nom_con) && (liste->largeur > largeurmax))
1661 ringerreur(ERR_CONLARGEUR, liste, NULL);
1662
1663 switch (liste->layer) {
1664 case ALU1:
1665 if (liste->largeur < WMIN_ALU1) /* ringerreur largeur connecteur */
1666 ringerreur(ERR_CONLARGEUR, liste, NULL);
1667 break;
1668 case ALU2:
1669 if (liste->largeur < WMIN_ALU2) /* ringerreur largeur connecteur */
1670 ringerreur(ERR_CONLARGEUR, liste, NULL);
1671 break;
1672 default :
1673 ringerreur(ERR_CONLARGEUR, liste, NULL);
1674 }
1675
1676 position = (liste->coord)->xabs + (tab_plots[face].coord).xabs;
1677 (liste->coord)->xabs = position;
1678 (liste->coord)->yabs = tab_plots[face].coord.yabs;
1679 (liste->coord)->piste = (tab_plots[face].coord).piste;
1680
1681 if (mode_debug)
1682 printf("position %ld du connecteur %s face %d\n", position, liste->nom_con, face);
1683
1684 liste = liste->suiv;
1685 } /* fin du while */
1686 break;
1687
1688 case EST :
1689 case OUEST:
1690 //niveau = xmetal;
1691 //largeurmin = xmetal_width;
1692
1693 while (liste != NULL) {
1694 if (mode_debug)
1695 printf("\t%s width=%ld y %ld ybarre %ld \n", liste->nom_con, liste->largeur, liste->coord->yabs,
1696 tab_plots[face].coord.yabs);
1697 if(!isvdd(liste->nom_con) && !isvss(liste->nom_con) && (liste->largeur > largeurmax))
1698 ringerreur(ERR_CONLARGEUR, liste, NULL);
1699
1700 switch (liste->layer) {
1701 case ALU1:
1702 if (liste->largeur < WMIN_ALU1) /* ringerreur largeur connecteur */
1703 ringerreur(ERR_CONLARGEUR, liste, NULL);
1704 break;
1705 case ALU2:
1706 if (liste->largeur < WMIN_ALU2) /* ringerreur largeur connecteur */
1707
1708 ringerreur(ERR_CONLARGEUR, liste, NULL);
1709 break;
1710 default :
1711 ringerreur(ERR_CONLARGEUR, liste, NULL);
1712 }
1713
1714 position = (liste->coord)->yabs + (tab_plots[face].coord).yabs;
1715 (liste->coord)->yabs = position;
1716 (liste->coord)->xabs = (tab_plots[face].coord).xabs;
1717 (liste->coord)->piste = (tab_plots[face].coord).piste;
1718
1719 if (mode_debug)
1720 printf("position %ld du connecteur %s face %d\n", position, liste->nom_con, face);
1721
1722 liste = liste->suiv;
1723 } /* fin du while */
1724 break;
1725 } /* fin du switch */
1726
1727 } /* fin du for */
1728 }
1729
1730 /*------------------------------------------------------------------------------------*/
1731 /* Fabrication de la grille finale a partir des connecteurs de plots. */
1732 /* Verification de la distance des connecteurs entre eux leur largeur */
1733 /* Mise a jour des futurs deports. */
1734 /* */
1735 /* Rq: la dmin a1 a1 est de 3 cad 30 avec le SCALE_X actuel, pour faire les nouveaux */
1736 /* pas de grille, on se sert de dmin/2, mais les pas doivent etre multiples de */
1737 /* scale_x, donc pour les calculs des nouveaux pas on prend */
1738 /* ((pos + scale_x/2) /scale_x) *scale_x */
1739 /*------------------------------------------------------------------------------------*/
1740
fabrique_grille_finale(BARRE_PLOTS tab_plots[NB_FACES],LST_PSEUDO_CON tab_coeur[NB_FACES],COEUR lecoeur,LST_EQUIPO lst_equipo,GRILLE tab_grilles[NB_FACES])1741 void fabrique_grille_finale(BARRE_PLOTS tab_plots[NB_FACES],
1742 LST_PSEUDO_CON tab_coeur[NB_FACES], COEUR lecoeur,
1743 LST_EQUIPO lst_equipo, GRILLE tab_grilles[NB_FACES])
1744 {
1745 LST_PSEUDO_CON liste, liste_coeur;
1746 int face;
1747 long position;
1748
1749 if (mode_debug)
1750 printf("Fabrique grille finale\n");
1751 if (mode_debug)
1752 printf("Coord coeur x%ld y%ld w%ld h%ld\n", lecoeur.coord.xabs, lecoeur.coord.yabs, lecoeur.width, lecoeur.height);
1753
1754 for (face = 0; face < NB_FACES; face++) {
1755 liste = tab_plots[face].lst_con;
1756 liste_coeur = tab_coeur[face];
1757
1758 if (mode_debug)
1759 printf("Face %d\n", face);
1760
1761 switch (face) {
1762 case NORD:
1763 case SUD :
1764 //niveau = ymetal;
1765 //largeurmin = ymetal_width;
1766
1767 while (liste != NULL) {
1768 if (mode_debug)
1769 printf("\t%s\n", liste->nom_con);
1770
1771 if (moins_dun_pitch_preccon(liste))
1772 ringerreur(ERR_CONDISTANCE, liste, NULL);
1773
1774 position = (liste->coord)->xabs;
1775
1776 if (mode_debug)
1777 printf("position %ld du connecteur %s face %d\n", position, liste->nom_con, face);
1778
1779 if(!isvdd(liste->nom_con) && !isvss(liste->nom_con)) {
1780
1781 /* --------------------------- */
1782 /* en dehors du coeur = deport */
1783 /* --------------------------- */
1784
1785 if (position < (lecoeur.coord).xabs) {
1786 if (mode_debug)
1787 printf("Deportg connecteur %s %ld\n", liste->nom_con, position);
1788 alloue_coord(0L, 0, &(liste->deport));
1789 /* liste->deport = (PT_COORDONNEES) mbkalloc ((unsigned int) sizeof(COORDONNEES)); */
1790
1791 (liste->deport)->piste = 0; /* deport uniquement pour differencier du layer */
1792
1793 ajout_coordonnees_grille(liste->coord, &(tab_grilles[face].lst_deportg),
1794 face);
1795 } else if (position > ((lecoeur.coord).xabs + lecoeur.width)) {
1796 if (mode_debug)
1797 printf("Deportd connecteur %s %ld\n", liste->nom_con, position);
1798 alloue_coord(0L, 0, &(liste->deport));
1799 /* liste->deport = (PT_COORDONNEES) mbkalloc ((unsigned int) sizeof(COORDONNEES)); */
1800
1801 (liste->deport)->piste = 0; /* deport uniquement pour differencier du layer */
1802
1803 ajout_coordonnees_grille(liste->coord, &(tab_grilles[face].lst_deportd),
1804 face);
1805 } else if (moins_dun_pitch_confacecoeur(position, liste, liste_coeur, lst_equipo,
1806 face)) { /* Ne forme pas un nouveau pas de grille */
1807 if (mode_debug)
1808 printf("Deport connecteur %s\n", liste->nom_con);
1809 alloue_coord(0L, 0, &(liste->deport));
1810 /* liste->deport = (PT_COORDONNEES) mbkalloc ((unsigned int) sizeof(COORDONNEES)); */
1811
1812 (liste->deport)->piste = 0; /* deport uniquement pour differencier du layer */
1813 } else
1814 {
1815 if (mode_debug)
1816 printf("Nouveau pas connecteur %s %ld\n", liste->nom_con, position);
1817
1818 ajout_coordonnees_grille(liste->coord, &(tab_grilles[face].lst_pas), face);
1819 }
1820
1821 } /* fin du if */ else {
1822
1823 /* ------------------------------------------------------------------------- */
1824 /* Il s'agit d'un plot d'alimentation, c'est un pas obligatoire de la grille */
1825 /* si ringerreur ici => ringerreur dans le placement de la barre de plot! */
1826 /* ------------------------------------------------------------------------- */
1827
1828 if (position < (lecoeur.coord).xabs)
1829 ringerreur(ERR_BARREALIM, (void * ) & face, NULL);
1830 if (position > ((lecoeur.coord).xabs + lecoeur.width))
1831 ringerreur(ERR_BARREALIM, (void * ) & face, NULL);
1832
1833 moins_dun_pitch_confacecoeur(position, liste, liste_coeur, lst_equipo, face);
1834 if (mode_debug)
1835 printf("Nouveau pas ALIM connecteur %s %ld\n", liste->nom_con, position);
1836
1837 ajout_coordonnees_grille(liste->coord, &(tab_grilles[face].lst_pas), face);
1838 }
1839
1840 liste = liste->suiv;
1841 } /* fin du while */
1842 break;
1843
1844 case EST :
1845 case OUEST:
1846 //niveau = xmetal;
1847 //largeurmin = xmetal_width;
1848
1849 while (liste != NULL) {
1850 if (mode_debug)
1851 printf("\t%s y %ld ybarre %ld \n", liste->nom_con, liste->coord->yabs, tab_plots[face].coord.yabs);
1852
1853 if (moins_dun_pitch_preccon(liste))
1854 ringerreur(ERR_CONDISTANCE, liste, NULL);
1855
1856 position = (liste->coord)->yabs;
1857 if (mode_debug)
1858 printf("position %ld du connecteur %s face %d\n", position, liste->nom_con, face);
1859
1860 if(!isvdd(liste->nom_con) && !isvss(liste->nom_con)) {
1861
1862 /* --------------------------- */
1863 /* en dehors du coeur = deport */
1864 /* --------------------------- */
1865
1866 if (position < (lecoeur.coord).yabs) {
1867 if (mode_debug)
1868 printf("Deport connecteur %s %ld\n", liste->nom_con, position);
1869 alloue_coord(0L, 0, &(liste->deport));
1870 /* liste->deport = (PT_COORDONNEES) mbkalloc ((unsigned int) sizeof(COORDONNEES)); */
1871 (liste->deport)->piste = 0; /* deport uniquement pour differencier du layer */
1872
1873 ajout_coordonnees_grille(liste->coord, &(tab_grilles[face].lst_deportg),
1874 face);
1875 } else if (position > ((lecoeur.coord).yabs + lecoeur.height)) {
1876 if (mode_debug)
1877 printf("Deport connecteur %s %ld\n", liste->nom_con, position);
1878 alloue_coord(0L, 0, &(liste->deport));
1879 /* liste->deport = (PT_COORDONNEES) mbkalloc ((unsigned int) sizeof(COORDONNEES)); */
1880 (liste->deport)->piste = 0; /* deport uniquement pour differencier du layer */
1881
1882 ajout_coordonnees_grille(liste->coord, &(tab_grilles[face].lst_deportd),
1883 face);
1884 } else if (moins_dun_pitch_confacecoeur(position, liste, liste_coeur, lst_equipo,
1885 face)) {
1886 if (mode_debug)
1887 printf("Deport connecteur %s %ld\n", liste->nom_con, position);
1888 alloue_coord(0L, 0, &(liste->deport));
1889 /* liste->deport = (PT_COORDONNEES) mbkalloc ((unsigned int) sizeof(COORDONNEES)); */
1890 (liste->deport)->piste = 0; /* deport uniquement pour differencier du layer */
1891 } else
1892 {
1893 if (mode_debug)
1894 printf("Nouveau pas connecteur %s %ld\n", liste->nom_con, position);
1895
1896 ajout_coordonnees_grille(liste->coord, &(tab_grilles[face].lst_pas), face);
1897 }
1898
1899 } /* fin du if */ else {
1900
1901 /* ------------------------------------------------------------------------- */
1902 /* Il s'agit d'un plot d'alimentation, c'est un pas obligatoire de la grille */
1903 /* si ringerreur ici => ringerreur dans le placement de la barre de plot! */
1904 /* ------------------------------------------------------------------------- */
1905
1906 if (position < (lecoeur.coord).yabs)
1907 ringerreur(ERR_BARREALIM, (void * ) & face, NULL);
1908 if (position > ((lecoeur.coord).yabs + lecoeur.height))
1909 ringerreur(ERR_BARREALIM, (void * ) & face, NULL);
1910
1911 moins_dun_pitch_confacecoeur(position, liste, liste_coeur, lst_equipo, face);
1912 if (mode_debug)
1913 printf("Nouveau pas ALIM connecteur %s %ld\n", liste->nom_con, position);
1914
1915 ajout_coordonnees_grille(liste->coord, &(tab_grilles[face].lst_pas), face);
1916 }
1917
1918 liste = liste->suiv;
1919 } /* fin du while */
1920
1921 break;
1922 } /* Fin du switch() */
1923
1924 /*------------- AJOUT DE PAS SUPPLEMENTAIRES SI DIST ENTRE PAS >= 2 PITCH --------*/
1925
1926 ajout_pas_grille(tab_grilles, lecoeur, face);
1927
1928 } /* fin du for */
1929 }
1930
1931 /*------------------------------------------------------------------------------------*/
1932 /* Ajout de nouveaux pas de grille si distance entre connecteur est suffisante */
1933 /* Rq: la dmin a1 a1 est de 3 cad 30 avec le SCALE_X actuel, pour faire les nouveaux */
1934 /* pas de grille, on se sert de dmin/2, mais les pas doivent etre multiples de */
1935 /* scale_x, donc pour les calculs des nouveaux pas on prend pour a1 ou a2 */
1936 /* ((pos + scale_x) /scale_x) *scale_x */
1937 /* ceci est utilise quand connecteurs de largeur non standard sinon pas de pb */
1938 /* */
1939 /* bug corrige au niveau des calculs de pas (+lamda / lambda * lambda) */
1940 /* 13 sept 92: autre bug corrige. */
1941 /* Les connecteurs d'alim peuvent etre en vis a vis et se recouvrir, ce qui */
1942 /* faisait creer des nouveaux pas dans les alim ! */
1943 /* Les fonctions existe_con_prec et existe_con_suiv trouve le */
1944 /* connecteur le plus proche de celui qu'on cherche, donc une alim */
1945 /* recouvrant si elle existe, et repousse les nouveaux pas dans une */
1946 /* zone de routage vraiment libre. */
1947 /* */
1948 /* Attention: Le reglage pour les pas de grille est tres precis! */
1949 /* si modif, verifier a la main qu'on respecte les distances ds ts les cas ! */
1950 /*------------------------------------------------------------------------------------*/
1951
ajout_pas_grille(GRILLE tab_grilles[NB_FACES],COEUR lecoeur,int face)1952 void ajout_pas_grille(GRILLE tab_grilles[NB_FACES], COEUR lecoeur, int face)
1953 {
1954 PT_COORDONNEES coordalim, nouveau, c1, c2, liste_coor;
1955 long np = 0, enleve = 0, coordcon = 0, coordconprec = 0, largcon = 0, largconprec = 0;
1956 long debut1 = 0, fin1 = 0, dist = 0, largeurmin = 0, dminmetalmetal = 0;
1957 char layercon, layerconprec;
1958
1959 if (mode_debug)
1960 printf("FACE a completer %d\n", face);
1961
1962 liste_coor = tab_grilles[face].lst_pas;
1963
1964 /* --------------*/
1965 /* pour les vias */
1966 /* --------------*/
1967
1968 if (ymetal_dmin > xmetal_dmin)
1969 dminmetalmetal = ymetal_dmin;
1970 else
1971 dminmetalmetal = xmetal_dmin;
1972
1973 /*------------------ DEBUT DE GRILLE ----------------------------------------*/
1974 if (liste_coor != NULL)
1975 switch (face) {
1976 case NORD :
1977 case SUD :
1978 if (mode_debug)
1979 printf("1er coordonnee %ld\n", liste_coor->xabs);
1980 largeurmin = ymetal_wvia;
1981
1982 /* ----------------------------------------------------------- */
1983 /* on recherche si alim suivante recouvrant connecteur existe */
1984 /* ----------------------------------------------------------- */
1985
1986 liste_coor = existe_con_suiv(0L, 0L, ymetal_width, ymetal, face, tab_grilles[face].lst_pas);
1987 if (NULL == liste_coor)
1988 ringerreur(ERR_GRILLEINTERNE, NULL, NULL);
1989
1990 if (mode_debug)
1991 printf("1ER CONNECTEUR x %ld y %ld face %d\n\n", liste_coor->xabs, liste_coor->yabs, face);
1992
1993 if (((LST_PSEUDO_CON)liste_coor->proprio)->largeur > largeurmin) {
1994 enleve = ((LST_PSEUDO_CON)liste_coor->proprio)->largeur / 2 + dminmetalmetal + taille_via /
1995 2;
1996 if (((LST_PSEUDO_CON)liste_coor->proprio)->largeur < taille_via)
1997 enleve += ( taille_via / 2 - ((LST_PSEUDO_CON)liste_coor->proprio)->largeur / 2);
1998
1999 enleve = ((enleve + lambda) / lambda) * lambda;
2000 } else
2001 enleve = pitch;
2002
2003 for (np = (lecoeur.coord).xabs + pitch; np <= (liste_coor->xabs - enleve); np = np + pitch) {
2004
2005 /* ----------------------------------------- */
2006 /* ce for calcule les nouveaux pas de grille */
2007 /* ----------------------------------------- */
2008
2009 alloue_coord(np, face, &nouveau);
2010 ajout_coordonnees_grille(nouveau, &(tab_grilles[face].lst_pas), face);
2011 }
2012 break;
2013 case EST :
2014 case OUEST:
2015 if (mode_debug)
2016 printf("1er coordonnee %ld\n", liste_coor->yabs);
2017 largeurmin = xmetal_wvia;
2018
2019 /* ----------------------------------------------------------- */
2020 /* on recherche si alim suivante recouvrant connecteur existe */
2021 /* ----------------------------------------------------------- */
2022
2023 liste_coor = existe_con_suiv(0L, 0L, xmetal_width, xmetal, face, tab_grilles[face].lst_pas);
2024 if (NULL == liste_coor)
2025 ringerreur(ERR_GRILLEINTERNE, NULL, NULL);
2026
2027 if (mode_debug)
2028 printf("1ER CONNECTEUR x %ld y %ld face %d\n\n", liste_coor->xabs, liste_coor->yabs, face);
2029
2030 if (((LST_PSEUDO_CON)liste_coor->proprio)->largeur > largeurmin) {
2031 enleve = ((LST_PSEUDO_CON)liste_coor->proprio)->largeur / 2 + dminmetalmetal + taille_via /
2032 2;
2033 if (((LST_PSEUDO_CON)liste_coor->proprio)->largeur < taille_via)
2034 enleve += ( taille_via / 2 - ((LST_PSEUDO_CON)liste_coor->proprio)->largeur / 2);
2035
2036 enleve = ((enleve + lambda) / lambda) * lambda;
2037 } else
2038 enleve = pitch;
2039
2040 for (np = (lecoeur.coord).yabs + pitch; np <= (liste_coor->yabs - enleve); np = np + pitch) {
2041
2042 /* ----------------------------------------- */
2043 /* ce for calcule les nouveaux pas de grille */
2044 /* ----------------------------------------- */
2045
2046 alloue_coord(np, face, &nouveau);
2047 ajout_coordonnees_grille(nouveau, &(tab_grilles[face].lst_pas), face);
2048 }
2049 break;
2050 }
2051
2052 /*------------------------- GRILLE COURANTE --------------------------------*/
2053
2054 if (mode_debug)
2055 printf("Grille courante\n\n");
2056
2057 while ((liste_coor != NULL) && (liste_coor->suiv != NULL)) {
2058 c1 = liste_coor;
2059 c2 = liste_coor->suiv;
2060
2061 switch (face) {
2062 case NORD:
2063 case SUD :
2064 if (mode_debug)
2065 printf("grille courante 1er %ld\n", liste_coor->xabs);
2066 coordcon = c2->xabs;
2067 coordconprec = c1->xabs;
2068 break;
2069 case EST :
2070 case OUEST:
2071 coordcon = c2->yabs;
2072 coordconprec = c1->yabs;
2073 break;
2074 }
2075
2076 largcon = ((LST_PSEUDO_CON)c2->proprio)->largeur;
2077 layercon = ((LST_PSEUDO_CON)c2->proprio)->layer;
2078 largconprec = ((LST_PSEUDO_CON)c1->proprio)->largeur;
2079 layerconprec = ((LST_PSEUDO_CON)c1->proprio)->layer;
2080
2081 dist = distance_con_con(coordcon, coordcon, largcon, layercon, coordconprec, coordconprec, largconprec, layerconprec,
2082 face);
2083
2084 /* ---------------------------------------------------------------------- */
2085 /* on recherche si alim precedente recouvrant connecteur precedent existe */
2086 /* ---------------------------------------------------------------------- */
2087
2088 coordalim = existe_con_precalim(coordcon, coordcon, largcon, layercon, face, tab_grilles[face].lst_pas, dist);
2089
2090 if (NULL != coordalim) {
2091 if (mode_debug)
2092 printf("RECOUVRE TROUVE x %ld y %ld coordcon x %ld y %ld face %d DIST= %ld\n\n", coordalim->xabs,
2093 coordalim->yabs, coordcon, coordcon, face, dist);
2094 if ((NORD == face) || (SUD == face))
2095 coordconprec = coordalim->xabs;
2096 else
2097 coordconprec = coordalim->yabs;
2098 largconprec = ((LST_PSEUDO_CON)coordalim->proprio)->largeur;
2099 layerconprec = ((LST_PSEUDO_CON)coordalim->proprio)->layer;
2100 }
2101
2102 dist = distance_con_con(coordcon, coordcon, largcon, layercon, coordconprec, coordconprec, largconprec, layerconprec,
2103 face);
2104
2105 if ((largcon > largeurmin) || (largconprec > largeurmin)) {
2106 if (mode_debug)
2107 printf("largeur non standard\n %ld %ld", largconprec, largcon);
2108
2109 if (largconprec <= largeurmin)
2110 debut1 = pitch;
2111 else
2112 {
2113 debut1 = largconprec / 2 + dminmetalmetal + taille_via / 2;
2114 if (largconprec < taille_via)
2115 debut1 += (taille_via / 2 - largconprec / 2);
2116 debut1 = ((debut1 + lambda) / lambda) * lambda;
2117 }
2118
2119 if (largcon <= largeurmin)
2120 fin1 = pitch;
2121 else
2122 {
2123 fin1 = largcon / 2 + dminmetalmetal + taille_via / 2;
2124 if (largcon < taille_via)
2125 fin1 += (taille_via / 2 - largcon / 2);
2126
2127 fin1 = ((fin1 + lambda) / lambda) * lambda;
2128
2129 }
2130
2131 if (dist >= (2 * dminmetalmetal + largeurmin))
2132 for (np = coordconprec + debut1; np <= (coordcon - fin1); np = np + pitch) {
2133
2134 /* ------------------------------------------------- */
2135 /* ce for costaud calcule les nouveaux pas de grille */
2136 /* ------------------------------------------------- */
2137
2138 alloue_coord(np, face, &nouveau);
2139 ajout_coordonnees_grille(nouveau, &(tab_grilles[face].lst_pas), face);
2140 }
2141 } else
2142 {
2143 if (dist >= (2 * pitch))
2144 for (np = coordconprec + pitch; np <= (coordcon - pitch); np = np + pitch) {
2145 alloue_coord(np, face, &nouveau);
2146 ajout_coordonnees_grille(nouveau, &(tab_grilles[face].lst_pas), face);
2147 }
2148 }
2149
2150 /* ----------------------------------------------------------------------------------------------- */
2151 /* Si on a inserer de nouveaux elements il faut pas les traiter donc on prend c2 comme pas suivant */
2152 /* ----------------------------------------------------------------------------------------------- */
2153
2154 liste_coor = c2;
2155 } /*fin du while */
2156
2157 if (liste_coor != NULL) {
2158
2159 /*------------------------------- FIN DE GRILLE ----------------------------*/
2160
2161 switch (face) {
2162 case NORD :
2163 case SUD :
2164 /* ----------------------------------------------------------- */
2165 /* on recherche si alim suivante recouvrant connecteur existe */
2166 /* ----------------------------------------------------------- */
2167
2168 liste_coor = existe_con_suiv(lecoeur.width + lecoeur.coord.xabs, lecoeur.height + lecoeur.coord.yabs,
2169 ymetal_width, ymetal, face, tab_grilles[face].lst_pas);
2170 if (NULL == liste_coor)
2171 ringerreur(ERR_GRILLEINTERNE, NULL, NULL);
2172
2173 if (mode_debug)
2174 printf("Fin de grille dernier %ld\n", liste_coor->xabs);
2175
2176 if (((LST_PSEUDO_CON)liste_coor->proprio)->largeur > largeurmin) {
2177 enleve = ((LST_PSEUDO_CON)liste_coor->proprio)->largeur / 2 + dminmetalmetal + taille_via /
2178 2;
2179 if (((LST_PSEUDO_CON)liste_coor->proprio)->largeur < taille_via)
2180 enleve += ( taille_via / 2 - ((LST_PSEUDO_CON)liste_coor->proprio)->largeur / 2);
2181
2182 enleve = ((enleve + lambda) / lambda) * lambda;
2183 } else
2184 enleve = pitch;
2185
2186 for (np = liste_coor->xabs + enleve; np <= ((lecoeur.coord).xabs + lecoeur.width - pitch); np = np + pitch) {
2187 /* ------------------------------------------------ */
2188 /* ce for calcule les nouveaux pas en fin de grille */
2189 /* ------------------------------------------------ */
2190
2191 alloue_coord(np, face, &nouveau);
2192 ajout_coordonnees_grille(nouveau, &(tab_grilles[face].lst_pas), face);
2193 }
2194 break;
2195 case EST :
2196 case OUEST:
2197
2198 /* ----------------------------------------------------------- */
2199 /* on recherche si alim suivante recouvrant connecteur existe */
2200 /* ----------------------------------------------------------- */
2201
2202 liste_coor = existe_con_suiv(lecoeur.width + lecoeur.coord.xabs, lecoeur.height + lecoeur.coord.yabs,
2203 xmetal_width, xmetal, face, tab_grilles[face].lst_pas);
2204 if (NULL == liste_coor)
2205 ringerreur(ERR_GRILLEINTERNE, NULL, NULL);
2206
2207 if (mode_debug)
2208 printf("Fin de grille dernier %ld\n", liste_coor->yabs);
2209
2210 if (((LST_PSEUDO_CON)liste_coor->proprio)->largeur > largeurmin) {
2211 enleve = ((LST_PSEUDO_CON)liste_coor->proprio)->largeur / 2 + dminmetalmetal + taille_via /
2212 2;
2213 if (((LST_PSEUDO_CON)liste_coor->proprio)->largeur < taille_via)
2214 enleve += ( taille_via / 2 - ((LST_PSEUDO_CON)liste_coor->proprio)->largeur / 2);
2215
2216 enleve = ((enleve + lambda) / lambda) * lambda;
2217 } else
2218 enleve = pitch;
2219
2220 for (np = liste_coor->yabs + enleve; np <= ((lecoeur.coord).yabs + lecoeur.height - pitch); np = np + pitch) {
2221 /* ------------------------------------------------ */
2222 /* ce for calcule les nouveaux pas en fin de grille */
2223 /* ------------------------------------------------ */
2224
2225 alloue_coord(np, face, &nouveau);
2226 ajout_coordonnees_grille(nouveau, &(tab_grilles[face].lst_pas), face);
2227 }
2228 break;
2229 }
2230
2231 } /* fin du if != NULL */
2232
2233 }
2234
2235 /*----------------------------------------------------------------------------*/
2236 /* Cette procedure relie les plots eloignes par fabrique_barre avec la liste */
2237 /* lst_conestouest, cad relie les alim internes faces ouest et est */
2238 /*----------------------------------------------------------------------------*/
2239
relier_plots_wire1(phins_list * lastinst,phins_list * lastinst2,chain_list * lst)2240 void relier_plots_wire1(phins_list *lastinst, phins_list *lastinst2, chain_list *lst)
2241 {
2242 phcon_list * con1, *con2;
2243
2244 while (NULL != lst) {
2245 con2 = (phcon_list * ) lst->DATA;
2246 con1 = (phcon_list * ) lst->NEXT->DATA;
2247
2248 poser_wire1(con1->LAYER, con1->WIDTH / SCALE_X, lastinst->INSNAME, con1->NAME, con1->INDEX, lastinst2->INSNAME,
2249 con2->NAME, con2->INDEX);
2250
2251 lst = lst->NEXT->NEXT;
2252 }
2253
2254 }
2255