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