/****************************************************************************/
/*                                                                          */
/*                      Chaine de CAO & VLSI   Alliance                     */
/*                                                                          */
/*    Produit : ring router                                                 */
/*    Fichier : placement.c                                                 */
/*                                                                          */
/*    (c) copyright 1992 Laboratoire MASI equipe CAO & VLSI                 */
/*    Tous droits reserves                                                  */
/*    Support : e-mail cao-vlsi@masi.ibp.fr                                 */
/*                                                                          */
/*    Ecrit   par : Olivier Van Hautte                  le : 01/08/92       */
/*    Modifie par : Franck Wajsburt                     le :   /  /         */
/*                                                                          */
/****************************************************************************/

/*-----------------------------------------------------------------------------------*/

/* RING 15 juillet 92 ----------------------------------- PLACEMENT.C            */
/* PHASE 4 */

/* Les tableaux tab_plots tab_coeur et la liste des connecteurs speciaux sont remplies. */

#include <stdio.h>

#include "includes.h"
#include "struct.h"

/*-----------------------------------------------------------------------------------*/

/* Cette procedure initialise les structures de donneees necessaires au barres
   de plots . Elle prend les connecteurs de plots sur l'aboutement de la figure 
   physique de la barre construite precedemment. Si un connecteur n'existe pas 
   dans le niveau demande, on cree un deport, sera traite ulterieurement.            */

void remplir_tabplots(tab_plots, lst_equipo)
BARRE_PLOTS tab_plots[NB_FACES];
LST_EQUIPO lst_equipo;
{
	int	face, sansdeport = 0, avecdeport = 1;
	phfig_list * ptfig;
	phcon_list * liste_con;
	char	niveau;
	long	x, y, xarr, yarr;
	LST_PSEUDO_CON con;

	for (face = 0; face < NB_FACES; face++) {
		switch (face) {
		case NORD:
		case SUD : 
			niveau = ymetal;
			break;
		case EST :
		case OUEST: 
			niveau = xmetal;
			break;
		}

		if (tab_plots[face].width != 0) {
			ptfig = getphfig(tab_plots[face].nomfig, 'A');
			liste_con = ptfig->PHCON;

			while (liste_con != NULL) {
				/* 1ere passe, on ne prend que les connecteurs du layer de la face */

				if (liste_con->LAYER == niveau) {

#ifdef COMMENT
					/* ces 3 lignes uniquement pour test */

					con = existe_conplot_lstequipo(liste_con->NAME, lst_equipo);
					if ((con != NULL) && (con->nom_con == eq_vdd)) {
#endif
						/* Coordonnees du connecteur */

						x = liste_con->XCON;
						y = liste_con->YCON;

						/* Mise a plat des coordonnees par rapport a l'origine de la barre
             de plots */

						xyflat(&xarr, &yarr, x, y, 0L, 0L, ptfig->XAB1, ptfig->YAB1, ptfig->XAB2,
						                        ptfig->YAB2, NOSYM);

						/* Ajout du pseudo connecteur dans la liste associee a la face
             du plot */

						ajout_pseudo_con_plot(xarr, yarr, liste_con->WIDTH, liste_con->LAYER, liste_con->NAME,
						     face, sansdeport, tab_plots, lst_equipo);

#ifdef COMMENT
					}
#endif
				}

				liste_con = liste_con->NEXT;
			} /* fin du while parcours des conecteurs physiques */

			/*-------------------------------------------------------------------*/

			/* 2eme passe : on traite les connecteurs qui n'ont pas le bon layer */
			liste_con = ptfig->PHCON;

			while (liste_con != NULL) {

				if (liste_con->LAYER != niveau) {
					/* Coordonnees du connecteur */

					con = existe_conplot_lstequipo(liste_con->NAME, lst_equipo);

					if ((con != NULL) && (con->largeur == 0)) /* non traite */ {
						/* deport a effectuer */

						if (mode_debug) 
							printf("Deport mauvais layer %d connecteur %s\n", (int) niveau, liste_con->NAME);
						alloue_coord(0L, 0, &(con->deport));

						/*       				 con->deport = (PT_COORDONNEES) mbkalloc ((unsigned int) sizeof(COORDONNEES)); */
						(con->deport)->piste = 1; /* C'est un mauvais layer */

						con->deport->proprio = (void * ) con;

						x = liste_con->XCON;
						y = liste_con->YCON;

						/* Mise a plat des coordonnees par rapport a l'origine de la barre
             	 de plots */

						xyflat(&xarr, &yarr, x, y, 0L, 0L, ptfig->XAB1, ptfig->YAB1, ptfig->XAB2,
						                        ptfig->YAB2, NOSYM);

						/* Ajout du pseudo connecteur dans la liste associee a la face
	             du plot */

						ajout_pseudo_con_plot(xarr, yarr, liste_con->WIDTH, liste_con->LAYER, liste_con->NAME,
						     face, avecdeport, tab_plots, lst_equipo);
					} /* fin du 2eme if */
				} /* fin du 1er if */

				liste_con = liste_con->NEXT;
			} /* fin du while parcours des conecteurs physiques mauvais layer */

		} /* fin du if */ else 
			tab_plots[face].lst_con = NULL;

	} /* fin du for */

}

/*-----------------------------------------------------------------------------------*/

/* Cette procedure remplir le tableau de pseudo connecteurs du coeur, en les rangeant
   par face et par abscisse, x ou y selon la face horizontale ou verticale */

void remplir_tabcoeur(tabcoeur, lecoeur, lst_equipo)
LST_PSEUDO_CON tabcoeur[NB_FACES];
COEUR lecoeur;
LST_EQUIPO lst_equipo;
{

	long	x, y, xarr, yarr;
	phcon_list * liste_con = (lecoeur.coeur_ph)->PHCON;
	phfig_list * coeurph = lecoeur.coeur_ph;
	int	face;

	/* Initialisation du tableau de listes */

	for (face = 0; face < NB_FACES; face++)
		tabcoeur[face] = NULL;

	if (mode_debug) 
		printf("REMplir tabcoeur\n");

	if (liste_con == NULL)
		ringerreur(ERR_CONCOEUREMPTY, &lecoeur);

	while (liste_con != NULL) {
		/* Coordonnees du connecteur */

		x = liste_con->XCON;
		y = liste_con->YCON;

		/* Mise a plat des coordonnees par rapport a l'origine du coeur */

		xyflat(&xarr, &yarr, x, y, lecoeur.coord.xabs, lecoeur.coord.yabs, coeurph->XAB1, coeurph->YAB1, coeurph->XAB2,
		     				 coeurph->YAB2, lecoeur.rotation);

		/* Reorientation eventuelle du connecteur si le coeur a subi une rotation */

		face = reorientation_con(liste_con->ORIENT, NOSYM);

		/* Ajout du pseudo connecteur dans la liste associee a la face du coeur */

		ajout_pseudo_con_coeur(xarr, yarr, liste_con, face, tabcoeur, lst_equipo);
		liste_con = liste_con->NEXT;
	}

}

/*-----------------------------------------------------------------------------------*/

void affic_tabcoeur(tabcoeur)
LST_PSEUDO_CON tabcoeur[NB_FACES];
{

	int	i;

	for (i = 0; i < NB_FACES; i++) {
		printf("Affic lst face coeur no %d\n", i);
		affic_lstcon(tabcoeur[i]);
	}

}

/*-----------------------------------------------------------------------------------*/

void affic_tabplots(tabplot)
BARRE_PLOTS tabplot[NB_FACES];
{

	int	i;

	for (i = 0; i < NB_FACES; i++) {
		printf("Nomfig %s largeur %ld\n", tabplot[i].nomfig, tabplot[i].width);
		printf("Affic lst face barre de plots no %d\n", i);
		affic_lstcon(tabplot[i].lst_con);
	}

}

/*-----------------------------------------------------------------------------------*/

/* Calcul largeur des barres de plots et faces coeurs */

void largeur_ab_plots(tab_plots, nomplot, liste_plotsph)
BARRE_PLOTS tab_plots[NB_FACES];
chain_list  *nomplot[NB_FACES];
chain_list  *liste_plotsph;
{
	int	face, first;
	phfig_list * ptfig;
	long	largeur;
	chain_list * liste;

	/* Initialisations et calcul largeur ab d'une barre de plots */

	tab_plots[NORD].nomfig   = namealloc(FBARRE_N);
	tab_plots[NORD].nominst  = namealloc(IBARRE_N);
	tab_plots[SUD].nomfig    = namealloc(FBARRE_S);
	tab_plots[SUD].nominst   = namealloc(IBARRE_S);
	tab_plots[EST].nomfig    = namealloc(FBARRE_E);
	tab_plots[EST].nominst   = namealloc(IBARRE_E);
	tab_plots[OUEST].nomfig  = namealloc(FBARRE_O);
	tab_plots[OUEST].nominst = namealloc(IBARRE_O);

	for (face = 0; face < NB_FACES; face++) {
		first = 1;
		tab_plots[face].lst_con = NULL;
		tab_plots[face].nb_deport = 0;

		liste = nomplot[face];

		largeur = 0;

		while (liste != NULL) {
			if (mode_debug) 
				printf("figure %s\n", ((loins_list * )liste->DATA)->FIGNAME);

			if ((ptfig = appartient_listeplotsph(((loins_list * )liste->DATA)->FIGNAME, liste_plotsph)) != NULL) {
				if (first) { 
					first = 0; 
					tab_plots[face].height = ptfig->YAB2 - ptfig->YAB1;
				}

				largeur += (ptfig->XAB2 - ptfig->XAB1);
				if (mode_debug) 
					printf("largeur AB %ld plot %s \n", (ptfig->XAB2 - ptfig->XAB1), ((loins_list * )liste->DATA)->FIGNAME);
			}

			liste = liste->NEXT;
		}

		tab_plots[face].width = largeur;
	}

}

/*-----------------------------------------------------------------------------------*/

void fabrique_barre_plots(tab_plots, lecoeur, nomplot, liste_plotsph, lst_conestouest)
BARRE_PLOTS tab_plots[NB_FACES];
COEUR       lecoeur;
chain_list  *nomplot[NB_FACES];
chain_list  *liste_plotsph;
chain_list  *lst_conestouest;
{
	int	face, first;
	long	width_coeur, height_coeur, largeur;
	chain_list * liste;
	phfig_list * ptfig, *barre, *lastfig;
	long	diff, each, touslesnb, nbplotsface, x, y;
	long	nbplotsvidetot, cptplot, cptplotvide;
	double	nbeachvide;
	phins_list * firstinst, *lastinst, *lastinst2;

	/* Il faudra traiter cas rotation coeur */

	width_coeur  = lecoeur.width;
	height_coeur = lecoeur.height;

	largeur_ab_plots(tab_plots, nomplot, liste_plotsph);

	/* Construction des quatres barres de plots */

	for (face = 0; face < NB_FACES; face++) {
		if (tab_plots[face].width != 0)  /* Barre de plots definie */ {
			switch (face) {
			case EST:
			case OUEST: 
				largeur = height_coeur;
				break;
			case NORD:
			case SUD:   
				largeur = width_coeur;
				break;
			}

			if (tab_plots[face].width >= largeur) {
				if (mode_debug) 
					printf("face %d plots abutes simplement\n", face);

				liste = nomplot[face]; 
				first = 1;

				definir_fig_ph(tab_plots[face].nomfig);

				while (liste != NULL) {
					if (first) {
						first = 0;
						placer_instph(((loins_list * )liste->DATA)->FIGNAME, ((loins_list * )liste->DATA)->INSNAME,
						     NOSYM, 0L, 0L);
					} else
						abouteright_plot_fig(((loins_list * )liste->DATA)->FIGNAME, ((loins_list
						    *)liste->DATA)->INSNAME);
					liste = liste->NEXT;
				}

				definir_ab_fig();
			}  else /* barre plot < face du coeur */			 {
				if (mode_debug) 
					printf("Largeur barre < largeur coeur \n");

				nbplotsface = compte_nbplotsface(nomplot[face]);
				diff = largeur - tab_plots[face].width;
				nbplotsvidetot = diff / lambda;

				if (nbplotsvidetot < 1) {
					touslesnb = 1; 
					each = 0;
				} /* pas de plots vide a ajoute */ else
				 {
					if (1 != nbplotsface) 
						nbeachvide = nbplotsvidetot / (float) (nbplotsface - 1);
					else 
						nbeachvide = nbplotsvidetot / (float) nbplotsface;
					if (nbeachvide >= 1) {
						touslesnb = 1; 
						each = (long) nbeachvide;
					} else {
						touslesnb = (long) ((1 / nbeachvide) + 1); 
						each = 1;
					}
				}

				if (mode_debug) 
					printf("On ajoute %ld lambda de fils tous les %ld plots\n", each, touslesnb);

				liste = nomplot[face];
				cptplot = cptplotvide = 0; 
				first = 1;

				definir_fig_ph(tab_plots[face].nomfig);
				barre = getphfig(tab_plots[face].nomfig, 'A');

				while (liste != NULL) {
					if ((NULL != liste) && (0 != cptplot) && (0 == cptplot % touslesnb)) {
						firstlastinst_barre(barre, &firstinst, &lastinst);

						lastfig = getphfig(lastinst->FIGNAME, 'A');

						x = lastinst->XINS + lastfig->XAB2 - lastfig->XAB1 ; 
						y =  lastinst->YINS;
						cptplot++; 
						cptplotvide++;

						placer_instph(((loins_list * )liste->DATA)->FIGNAME, ((loins_list * )liste->DATA)->INSNAME
						    , NOSYM, (x + each * lambda) / SCALE_X , y / SCALE_X);

						firstlastinst_barre(barre, &firstinst, &lastinst2);

						relier_plots_wire1(lastinst, lastinst2, lst_conestouest);

						liste = liste->NEXT;
					} else
					 {
						if (first) {
							first = 0;
							placer_instph(((loins_list * )liste->DATA)->FIGNAME, ((loins_list
							    *)liste->DATA)->INSNAME, NOSYM, 0L, 0L);
						} else
							abouteright_plot_fig(((loins_list * )liste->DATA)->FIGNAME, ((loins_list
							    *)liste->DATA)->INSNAME);
						cptplot++;
						liste = liste->NEXT;
					}
				}

				definir_ab_fig();

				/* mise a jour de la largeur de la barre de plots */

				tab_plots[face].width += cptplotvide * each * lambda;

			}

		} /* fin du if largeur <> 0 */  else if /* largeur =0 else du 1er if */
		(mode_debug) 
			printf("barre face %d vide\n", face);

	}  /* fin du for */

	/* ON reprend chaque figure de plot et on remonte les connecteurs */
	for (face = 0; face < NB_FACES; face++) {
		if (tab_plots[face].width != 0) {
			liste = nomplot[face];

			definir_fig_ph(tab_plots[face].nomfig);

			while (liste != NULL) {
				if (existe_connecteur_faceplot(((loins_list * )liste->DATA)->FIGNAME, SUD, liste_plotsph))
					remonter_consud_instph(((loins_list * )liste->DATA)->INSNAME);
				liste = liste->NEXT;
			}

			if (mode_debug)	 
				sauver_fig_ph();
		}
	}

	/*
for (face=0; face < NB_FACES; face++)
	{
	if (tab_plots[face].largeur != 0)
		{
		ptfig = getphfig(tab_plots[face].nomfig,'A');
		viewphfig(ptfig);
		}
	}
*/

}

/*----------------------------------------------------------------------------*/

/* Fabrication de la grille primaire a partir des connecteurs du coeur.
   Verification de la distance des conecteurs entre eux leur largeur et leur
   niveau                                                                     */

void fabrique_grille_primaire(tab_coeur, tab_grilles)
LST_PSEUDO_CON tab_coeur[NB_FACES];
GRILLE         tab_grilles[NB_FACES];
{

	LST_PSEUDO_CON liste;
	int	face;
	char	niveau;
	long	largeurmin, largeurmax;

	if (WVIA_ALU1 > WVIA_ALU2) 
		largeurmax = WVIA_ALU1 * lambda;
	else 
		largeurmax = WVIA_ALU2 * lambda;

	if (mode_debug) 
		printf("Fabrique grille primaire \n");
	if (mode_debug) 
		printf("alu1 %d alu2 %d\n", ALU1, ALU2);

	for (face = 0; face < NB_FACES; face++) {
		liste = tab_coeur[face];

		if (mode_debug) 
			printf("Face %d\n", face);

		/* Initialisation de la grille */
		tab_grilles[face].lst_pas     = NULL;
		tab_grilles[face].lst_deportg = NULL;
		tab_grilles[face].lst_deportd = NULL;

		switch (face) {
		case NORD:
		case SUD :
			niveau = ymetal;
			largeurmin = ymetal_width;
			tab_grilles[face].piste.largeur_pas = pitch;
			break;

		case EST:
		case OUEST:
			niveau = xmetal;
			largeurmin = xmetal_width;
			tab_grilles[face].piste.largeur_pas = pitch;
			break;
		}

		while (liste != NULL) {
			if (mode_debug) 
				printf("connecteur %s\n", liste->nom_con);
			if (mode_debug) 
				printf("width connecteur %ld largeurmin %ld niveau requis %d\n", liste->largeur, largeurmin,
				     (int) niveau);

			if ((liste->nom_con != eq_vdd) && (liste->nom_con != eq_vss) && (liste->largeur > largeurmax)) 
				ringerreur(ERR_CONLARGEUR, liste);

			if (liste->layer != niveau) /* deport a effectuer */ {
				if (mode_debug) 
					printf("Deport mauvais layer %d connecteur %s\n", (int) liste->layer, liste->nom_con);
				alloue_coord(0L, 0, &(liste->deport));

				(liste->deport)->piste = 1; /* mauvais layer */
				liste->deport->proprio = (void * ) liste;

				switch (liste->layer) {
				case ALU1: 
					if (liste->largeur < WMIN_ALU1) /* ringerreur largeur connecteur */
						ringerreur(ERR_CONLARGEUR, liste);
					break;
				case ALU2: 
					if (liste->largeur < WMIN_ALU2) /* ringerreur largeur connecteur */
						ringerreur(ERR_CONLARGEUR, liste);

					break;
				}

			}   else if (liste->largeur < largeurmin) /* ringerreur largeur connecteur */
				ringerreur(ERR_CONLARGEUR, liste);

			if (moins_dun_pitch_preccon(liste))
				ringerreur(ERR_CONDISTANCE, liste);

			ajout_coordonnees_grille(liste->coord, &(tab_grilles[face].lst_pas), face);

			liste = liste->suiv;
		}  /* fin du while */

	} /* fin du for */

}

/*----------------------------------------------------------------------------*/
/* Cette procedure place chaque barre de plots par rapport a la face du coeur.
   Elle essaye plusieurs positions possibles pour chaque barre calule son cout
   en nombre de deports et garde la meilleure et la plus centree              */

void place_et_cout_barreplot(tab_coeur, tab_plots, lecoeur, lst_equipo)
LST_PSEUDO_CON tab_coeur[NB_FACES];
BARRE_PLOTS    tab_plots[NB_FACES];
COEUR          lecoeur;
LST_EQUIPO     lst_equipo;
{

	int	face, gauche, droite, haut, bas, cout, first;
	long	diff, barrexmilieu, barreymilieu, barrexcourant, barreycourant;

	if (mode_debug) 
		printf("PLACE barre plots\n");

	for (face = 0; face < NB_FACES; face++) {
		if (mode_debug) 
			printf("\n******************** FACE %d *************************\n", face);

		if (tab_plots[face].width != 0) {
			switch (face) {
			case NORD:
			case SUD :

				diff = tab_plots[face].width - lecoeur.width;

				if (mode_debug) 
					printf("diff barre - face coeur %ld\n", diff);

				if (diff >= 0)
					barrexmilieu = tab_plots[face].coord.xabs =  ((lecoeur.coord.xabs - diff / 2) / SCALE_X) *
					    SCALE_X;
					/* Largeur barre de plots >= largeur coeur */

				else
					barrexmilieu = tab_plots[face].coord.xabs =  ((lecoeur.coord.xabs - diff / 2) / SCALE_X) *
					    SCALE_X;
				/* Largeur barre de plots < largeur coeur */

				/* La barre de plots est centree sur le coeur */
				/* Nb iterations a effectuer en deplacant la barre vers la gauche
            puis vers la droite, on garde la position la plus centree avec
            le moins de deports */

				if (mode_debug) 
					printf("face %d debutbarremilieu %ld\n", face, barrexmilieu);
				first = 1;

				for (gauche = 0; gauche <= (NB_ITERATIONS / 2); gauche++) {
					barrexcourant = barrexmilieu - (gauche * lambda);
					if (mode_debug) 
						printf("\tbarrexcourant %ld", barrexcourant);
					if (conplotalim_dans_coeur(lst_equipo, lecoeur, barrexcourant, face))

						if (first) {
							if (mode_debug) 
								printf("first place barre alim sont ok\n");
							first = 0;
							tab_plots[face].nb_deport = calcul_nbdeport(tab_plots, tab_coeur,
							     lecoeur, lst_equipo, barrexcourant, face);
							tab_plots[face].coord.xabs = barrexcourant;
						}
						else
						 {
							if (mode_debug) 
								printf("place barre alim sont ok\n");
							if ((cout = calcul_nbdeport(tab_plots, tab_coeur, lecoeur, lst_equipo,
							     barrexcourant, face)) < tab_plots[face].nb_deport) {
								if (mode_debug) 
/* code folded from here */
	printf("Nouveau cout bestg %d barrexcourant %ld\n",
	     cout, barrexcourant);
/* unfolding */
								tab_plots[face].nb_deport = cout;
								tab_plots[face].coord.xabs = barrexcourant;
							}
						}
				}

				/* parcours droit, on repart du milieu */

				for (droite = 1; droite <= (NB_ITERATIONS / 2); droite++) {
					barrexcourant = barrexmilieu + (droite * lambda);
					if (mode_debug) 
						printf("\tbarrexcourant %ld", barrexcourant);
					if (conplotalim_dans_coeur(lst_equipo, lecoeur, barrexcourant, face))

						if (first) {
							if (mode_debug) 
								printf("first place barre alim sont ok\n");
							first = 0;
							tab_plots[face].nb_deport = calcul_nbdeport(tab_plots, tab_coeur,
							     lecoeur, lst_equipo, barrexcourant, face);
							tab_plots[face].coord.xabs = barrexcourant;
						}
						else
						 {
							if (mode_debug) 
								printf("place barre alim sont ok\n");
							if ((cout = calcul_nbdeport(tab_plots, tab_coeur, lecoeur, lst_equipo,
							     barrexcourant, face)) < tab_plots[face].nb_deport) {
								if (mode_debug) 
/* code folded from here */
	printf("Nouveau cout bestd %d barrexcourant %ld\n",
	     cout, barrexcourant);
/* unfolding */
								tab_plots[face].nb_deport = cout;
								tab_plots[face].coord.xabs = barrexcourant;
							} else if /* test egalite et proximite du milieu */
							/* vrai si egalite et position retenue precedemment etait a gauche
                         du milieu et si position courante droite est plus proche du milieu
                        que la gauche, on garde la plus centree, uggh ! */

							((cout == tab_plots[face].nb_deport) && (tab_plots[face].coord.xabs <=
							    barrexmilieu) && ((barrexcourant - barrexmilieu) < (barrexmilieu -
							    tab_plots[face].coord.xabs))) {
								if (mode_debug) 
/* code folded from here */
	printf("Nouveau cout bestd centree %d barrexcourant %ld\n",
	     cout, barrexcourant);
/* unfolding */
								tab_plots[face].coord.xabs = barrexcourant;
							}
						} /* fin du else */
				} /* fin du for */

				break; /* Fin Nord Sud */

			case EST  :
			case OUEST:

				diff = tab_plots[face].width - lecoeur.height;
				if (mode_debug) 
					printf("diff barre - face coeur %ld\n", diff);

				if (diff >= 0)
					barreymilieu = tab_plots[face].coord.yabs =  ((lecoeur.coord.yabs - diff / 2) / SCALE_X) *
					    SCALE_X;
					/* Hauteur barre de plots >= Hauteur coeur */

				else
					barreymilieu = tab_plots[face].coord.yabs =  ((lecoeur.coord.yabs - diff / 2) / SCALE_X) *
					    SCALE_X;
				/* Hauteur barre de plots < Hauteur coeur */

				/* La barre de plots est centree sur le coeur */
				/* Nb iterations a effectuer en deplacant la barre vers le bas
            puis vers le haut, on garde la position la plus centree avec
            le moins de deports */

				if (mode_debug) 
					printf("face %d debutbarremilieu %ld\n", face, barreymilieu);

				first = 1;

				for (bas = 0; bas <= (NB_ITERATIONS / 2); bas++) {
					barreycourant = barreymilieu - (bas * lambda);
					if (mode_debug) 
						printf("\tbarreycourant %ld", barreycourant);

					if (conplotalim_dans_coeur(lst_equipo, lecoeur, barreycourant, face))

						if (first) {
							if (mode_debug) 
								printf("first place barre alim sont ok\n");
							first = 0;
							tab_plots[face].nb_deport = calcul_nbdeport(tab_plots, tab_coeur,
							     lecoeur, lst_equipo, barreycourant, face);
							tab_plots[face].coord.yabs = barreycourant;
						}
						else
						 {
							if (mode_debug) 
								printf("place barre alim sont ok\n");
							if ((cout = calcul_nbdeport(tab_plots, tab_coeur, lecoeur, lst_equipo,
							     barreycourant, face)) < tab_plots[face].nb_deport) {
								if (mode_debug) 
/* code folded from here */
	printf("Nouveau cout bestb %d barreycourant %ld\n",
	     cout, barreycourant);
/* unfolding */
								tab_plots[face].nb_deport = cout;
								tab_plots[face].coord.yabs = barreycourant;
							}
						}
				}

				/* parcours haut, on repart du milieu */

				for (haut = 1; haut <= (NB_ITERATIONS / 2); haut++) {
					barreycourant = barreymilieu + (haut * lambda);
					if (mode_debug) 
						printf("\tbarreycourant %ld", barreycourant);

					if (conplotalim_dans_coeur(lst_equipo, lecoeur, barreycourant, face))

						if (first) {
							if (mode_debug) 
								printf("first place barre alim sont ok\n");
							first = 0;
							tab_plots[face].nb_deport = calcul_nbdeport(tab_plots, tab_coeur,
							     lecoeur, lst_equipo, barreycourant, face);
							tab_plots[face].coord.yabs = barreycourant;
						}
						else
						 {
							if (mode_debug) 
								printf("place barre alim sont ok\n");

							if ((cout = calcul_nbdeport(tab_plots, tab_coeur, lecoeur, lst_equipo,
							     barreycourant, face)) < tab_plots[face].nb_deport) {
								if (mode_debug) 
/* code folded from here */
	printf("Nouveau cout besth %d barreycourant %ld\n",
	     cout, barreycourant);
/* unfolding */
								tab_plots[face].nb_deport = cout;
								tab_plots[face].coord.yabs = barreycourant;
							} else if /* test egalite et proximite du milieu */
							/* vrai si egalite et position retenue precedemment etait en bas
                        du milieu et si position courante haute est plus proche du milieu
                       que celle du bas, on garde la plus centree, uggh ! */

							((cout == tab_plots[face].nb_deport) && (tab_plots[face].coord.yabs <=
							    barreymilieu) && ((barreycourant - barreymilieu) < (barreymilieu -
							    tab_plots[face].coord.yabs))) {
								if (mode_debug) 
/* code folded from here */
	printf("Nouveau cout besth centre %d barreycourant %ld\n",
	     cout, barreycourant);
/* unfolding */
								tab_plots[face].coord.yabs = barreycourant;
							}
						}
				}

				break; /* Fin Est Ouest */
			} /* Fin du switch */

			if (first) /* Ce qui veut dire qu'on a pas pu placer la barre de plot a cause des 
				                alim */
				ringerreur(ERR_BARREALIM, (void * ) & face);

			if (mode_debug) 
				printf("Placement de la barre %d xabs %ld yabs  %ld\n", face, tab_plots[face].coord.xabs,
				     tab_plots[face].coord.yabs);
		} /* Fin du if barre existante */

	} /* Fin du for */

	place_vertical_barreplot(tab_plots, tab_coeur, lecoeur, lst_equipo);
}

/*-------------------------------------------------------------------------------*/
/* Placement vertical des barres de plots = maximum des 4 faces. Pour chaque face 
   nb connect coeur + nb connect plot + 2 fois largalim                            */

void place_vertical_barreplot(tab_plots, tab_coeur, lecoeur, lst_equipo)
BARRE_PLOTS tab_plots[NB_FACES];
LST_PSEUDO_CON tab_coeur[NB_FACES];
COEUR lecoeur;
LST_EQUIPO lst_equipo;
{
	LST_EQUIPO equipo_vdd, equipo_vss;
	LST_PSEUDO_CON liste;
	int	face;
	long	largvdd, largvss, diff1, diff2, diff;

	long	cptcon = 0, maxcoeur = 0, maxplot = 0, largalim, dist;

	recherche_equipo_alim(&equipo_vdd, &equipo_vss, lst_equipo);

	largeur_vddvss(equipo_vdd, equipo_vss, &largvdd, &largvss);

	if (largvdd < largvss) 
		largalim = largvss; 
	else 
		largalim = largvdd;

	for (face = 0; face < NB_FACES; face++) {

		if (tab_plots[face].width != 0) {
			liste = tab_plots[face].lst_con;
			cptcon = 0;

			while (liste != NULL) { 
				cptcon++; 
				liste = liste->suiv; 
			}
			if (cptcon > maxplot) 
				maxplot = cptcon;

			liste = tab_coeur[face];
			cptcon = 0;

			while (liste != NULL) { 
				cptcon++; 
				liste = liste->suiv; 
			}

			if (cptcon > maxcoeur) 
				maxcoeur = cptcon;
		}
	}

	dist = (maxcoeur * pitch + maxplot * pitch + 2 * largalim) * 2;

	for (face = 0; face < NB_FACES; face++)
		(tab_plots[face].coord).piste = dist / pitch;

	if (tab_plots[NORD].width != 0)
		(tab_plots[NORD].coord).yabs = (lecoeur.coord).yabs + lecoeur.height + dist;
	if (tab_plots[SUD].width != 0)
		(tab_plots[SUD].coord).yabs = (lecoeur.coord).yabs - dist;
	if (tab_plots[OUEST].width != 0)
		(tab_plots[OUEST].coord).xabs = (lecoeur.coord).xabs - dist;
	if (tab_plots[EST].width != 0)
		(tab_plots[EST].coord).xabs = (lecoeur.coord).xabs + lecoeur.width + dist;

	if (mode_debug) 
		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,
		     (tab_plots[NORD].coord).yabs, (tab_plots[SUD].coord).xabs, (tab_plots[SUD].coord).yabs, (tab_plots[OUEST].coord).xabs,
		     (tab_plots[OUEST].coord).yabs, (tab_plots[EST].coord).xabs, (tab_plots[EST].coord).yabs);
	/*-------------  VERIFICATION DU NON CROISEMEMT DES BARRES MITOYENNES ----------*/

	for (face = 0; face < NB_FACES; face++) {
		diff1 = diff2 = 0;

		if (0 != tab_plots[face].width)
			switch (face) {
			case NORD:
				if (mode_debug) 
					printf("nord\t");
				if (0 != tab_plots[EST].width)
					diff1 = ((lecoeur.coord.yabs + lecoeur.height + tab_plots[NORD].coord.piste * pitch)
					    -(tab_plots[EST].coord.yabs + tab_plots[EST].width));
				if (0 != tab_plots[OUEST].width)
					diff2 = ((lecoeur.coord.yabs + lecoeur.height + tab_plots[NORD].coord.piste * pitch)
					    -(tab_plots[OUEST].coord.yabs + tab_plots[OUEST].width));

				if (diff1 < diff2) 
					diff = diff1; 
				else 
					diff = diff2;
				if (diff < 0) 
					tab_plots[NORD].coord.piste += ((-diff + pitch) / pitch);

				break;

			case SUD:
				if (mode_debug) 
					printf("sud\t");
				if (0 != tab_plots[EST].width)
					diff1 = ( -(lecoeur.coord.yabs - tab_plots[SUD].coord.piste * pitch) + (tab_plots[EST].coord.yabs));
				if (0 != tab_plots[OUEST].width)
					diff2 = ( -(lecoeur.coord.yabs - tab_plots[SUD].coord.piste * pitch) + (tab_plots[OUEST].coord.yabs));

				if (diff1 < diff2) 
					diff = diff1; 
				else 
					diff = diff2;
				if (diff < 0) 
					tab_plots[SUD].coord.piste += ((-diff + pitch) / pitch);

				break;

			case EST:
				if (mode_debug) 
					printf("est\t");
				if (0 != tab_plots[NORD].width)
					diff1 = ((lecoeur.coord.xabs + lecoeur.width + tab_plots[EST].coord.piste * pitch) -
					    (tab_plots[NORD].coord.xabs + tab_plots[NORD].width));
				if (0 != tab_plots[SUD].width)
					diff2 = ((lecoeur.coord.xabs + lecoeur.width + tab_plots[EST].coord.piste * pitch) -
					    (tab_plots[SUD].coord.xabs + tab_plots[SUD].width));

				if (diff1 < diff2) 
					diff = diff1; 
				else 
					diff = diff2;
				if (diff < 0) 
					tab_plots[EST].coord.piste += ((-diff + pitch) / pitch);
				break;

			case OUEST:
				if (mode_debug) 
					printf("ouest\t");
				if (0 != tab_plots[NORD].width)
					diff1 = (-(lecoeur.coord.xabs - tab_plots[OUEST].coord.piste * pitch ) + (tab_plots[NORD].coord.xabs));

				if (0 != tab_plots[SUD].width)
					diff2 = (-(lecoeur.coord.xabs - tab_plots[OUEST].coord.piste * pitch ) + (tab_plots[SUD].coord.xabs));

				if (diff1 < diff2) 
					diff = diff1; 
				else 
					diff = diff2;
				if (diff < 0) 
					tab_plots[OUEST].coord.piste += ((-diff + pitch) / pitch);
				break;
			}
	} /* fin du for */

	if (tab_plots[NORD].width != 0)
		(tab_plots[NORD].coord).yabs = tab_plots[NORD].coord.piste * pitch + lecoeur.height;
	if (tab_plots[SUD].width != 0)
		(tab_plots[SUD].coord).yabs = (lecoeur.coord).yabs - tab_plots[SUD].coord.piste * pitch;
	if (tab_plots[OUEST].width != 0)
		(tab_plots[OUEST].coord).xabs = (lecoeur.coord).xabs - tab_plots[OUEST].coord.piste * pitch;
	if (tab_plots[EST].width != 0)
		(tab_plots[EST].coord).xabs = (lecoeur.coord).xabs + lecoeur.width + tab_plots[EST].coord.piste * pitch;

	if (mode_debug) 
		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,
		     (tab_plots[NORD].coord).yabs, (tab_plots[SUD].coord).xabs, (tab_plots[SUD].coord).yabs, (tab_plots[OUEST].coord).xabs,
		     (tab_plots[OUEST].coord).yabs, (tab_plots[EST].coord).xabs, (tab_plots[EST].coord).yabs);

}

/*-------------------------------------------------------------------------------*/
/* Cette procedure calcule le nombre total de deport de la barre de plot placee
   a barrecourant. Cout des alim, connecteurs de plots a deporter, calcul du nombres
   de cycles. 
   nb: la fonction moins_dun_pitch_confacecoeur met a jour la liste des vis a vis    */

int	calcul_nbdeport(tab_plots, tab_coeur, lecoeur, lst_equipo, barrecourant, face)
BARRE_PLOTS    tab_plots[NB_FACES];
LST_PSEUDO_CON tab_coeur[NB_FACES];
COEUR          lecoeur;
LST_EQUIPO     lst_equipo;
long	barrecourant;
int	face;
{
	int	nbdepalim = 0, nbdepplots = 0, nbdepcycles = 0, nbdeptotal;
	long	position;
	LST_PSEUDO_CON liste_plots, liste_coeur;
	LST_EQUIPO     liste_eq;

	/* Calcul du nombre de deport provoques par l'alim par rapport au pitch */

	if (mode_debug) 
		printf("\tCalcul_nbdeport\n");

	nbdepalim = calcul_nbdeport_equipo_alim(lst_equipo, barrecourant, face);

	liste_eq    = lst_equipo;
	liste_plots = tab_plots[face].lst_con;
	liste_coeur = tab_coeur[face];

	/* Mise a nulle des listes de vis a vis des equipo */
	while (liste_eq) {
		liste_eq->lst_visavis = NULL; /* prevoir desallocation */
		liste_eq = liste_eq->suiv;
	}

	switch (face) {
	case NORD:
	case SUD :

		while (liste_plots != NULL) {
			if (mode_debug) 
				printf("\t%s\n", liste_plots->nom_con);

			if ((liste_plots->nom_con != eq_vdd) && (liste_plots->nom_con != eq_vss)) {
				position = (liste_plots->coord)->xabs + barrecourant;

				if (mode_debug) 
					printf("position %ld du connecteur %s face %d\n", position, liste_plots->nom_con,
					     face);

				/* en dehors du coeur = deport */

				if ((position < lecoeur.coord.xabs) ||  (position > (lecoeur.coord.xabs + lecoeur.width))) { 
					if (mode_debug) 
						printf("deport en dehors coeur\t");
					nbdepplots++;
				}  else if (moins_dun_pitch_confacecoeur(position, liste_plots , liste_coeur, lst_equipo,
				     face)) { 
					if (mode_debug) 
						printf("deport - 1 pitch\t");
					nbdepplots++;
				}

			} /* fin du if */

			liste_plots = liste_plots->suiv;
		}  /* fin du while */

		break;

	case EST  :
	case OUEST:

		while (liste_plots != NULL) {
			if (mode_debug) 
				printf("\t%s\n", liste_plots->nom_con);

			if ((liste_plots->nom_con != eq_vdd) && (liste_plots->nom_con != eq_vss)) {
				position = (liste_plots->coord)->yabs + barrecourant;

				if (mode_debug) 
					printf("position %ld du connecteur %s face %d\n", position, liste_plots->nom_con,
					     face);

				/* en dehors du coeur = deport */

				if ((position < lecoeur.coord.yabs) ||  (position > (lecoeur.coord.yabs + lecoeur.height))) { 
					if (mode_debug) 
						printf("deport en dehors coeur\t");
					nbdepplots++;
				}  else if (moins_dun_pitch_confacecoeur(position, liste_plots , liste_coeur, lst_equipo,
				     face)) { 
					if (mode_debug) 
						printf("deport - 1 pitch\n");
					nbdepplots++;
				}

			}

			liste_plots = liste_plots->suiv;
		}

		break;
	}  /* Fin du switch() */

	if (mode_debug) 
		printf("\tNb depplots %d", nbdepplots);

	/* Par la methode deroutage , il n'y aura pas de cycles,
 donc inutile de calculer les cycles eventuels */
	/* nbdepcycles = calcul_nbdeport_cyclesface(lst_equipo); */

	nbdeptotal = nbdepalim + nbdepplots + nbdepcycles;

	if (nbdeptotal < 0) 
		nbdeptotal = 0;

	if (mode_debug) 
		printf("Nombre total de deport %d pour face %d et barrecourant %ld\n", nbdeptotal, face, barrecourant);

	return(nbdeptotal);

}

/*--------------------------------------------------------------------------------*/

/* Cette fonction retourne vrai 1 si la position du connecteur plot est a moins d'un
  pitch d'un connecteur quelconque du coeur, sinon 0; et mets a jour la liste des
  vis a vis des equipo pour calcul ulterieur du nombre de cycle pour la face         */

/* Utilisation de la fonction calcul distance entre 2 connecteurs */

int	moins_dun_pitch_confacecoeur(position, plotcon, liste_coeur, lst_equipo, face)
long	position;
LST_PSEUDO_CON plotcon;
LST_PSEUDO_CON liste_coeur;
LST_EQUIPO     lst_equipo;
int	face;
{
	long	dist, largcon, largconprec, largeurmin, dminmetalmetal;
	long	coordcon, coordconprec;

	if (liste_coeur == NULL) 
		return(0); /* pas de connecteurs coeurs donc grille
	                                    formee par les con de plots */

	switch (face) {
	case NORD:
	case SUD :
		if ((liste_coeur->layer != ymetal) || (plotcon->layer != ymetal)) {
			if (ymetal_width < xmetal_width) 
				largeurmin = ymetal_width;
			else 
				largeurmin = xmetal_width;
			/*    dminmetalmetal = xmetal_dmin; */
			dminmetalmetal = ymetal_dmin;
		} else
		 {
			largeurmin = ymetal_width;
			dminmetalmetal = ymetal_dmin;
		}

		while (liste_coeur != NULL) {
			dist = distance_con_con(liste_coeur->coord->xabs, 0L, liste_coeur->largeur, liste_coeur->layer, position,
			     0L, plotcon->largeur, plotcon->layer, face);

			if ((liste_coeur->largeur > largeurmin) || (plotcon->largeur > largeurmin)) {

				/*
if (mode_debug) printf("confacecoeur coordcon %ld coordconprec %ld largcon %ld largconprec %ld dist %ld\n",
coordcon,coordconprec,largcon,largconprec,dist);  
*/

				if (dist < dminmetalmetal) {
					ajout_visavis(lst_equipo, liste_coeur, ((plotcon->con_lo)->SIG)->INDEX);
					if ((plotcon->nom_con != eq_vdd) && (plotcon->nom_con != eq_vss))
						return(1);
					/* pas de deport s'il s'agit d'une alim, on continue a parcourir */
				}
			}  else				 {
				if (dist  < pitch) {
					if (mode_debug) 
						printf("visavis posconcoeur %ld position %ld\n", (liste_coeur->coord)->xabs,
						     position);

					ajout_visavis(lst_equipo, liste_coeur, ((plotcon->con_lo)->SIG)->INDEX);
					return(1);  /* deport a faire */
				}
			} /* fin du else */

			liste_coeur = liste_coeur->suiv;
		} /* fin du while */

		return(0); /* Pas d'ringerreur c'est lesieur */

		break;

	case EST  :
	case OUEST:
		if ((liste_coeur->layer != xmetal) || (plotcon->layer != xmetal)) {
			if (ymetal_width < xmetal_width) 
				largeurmin = ymetal_width;
			else 
				largeurmin = xmetal_width;
			dminmetalmetal = xmetal_dmin;
		} else
		 {
			largeurmin = xmetal_width;
			dminmetalmetal = xmetal_dmin;
		}

		while (liste_coeur != NULL) {
			dist = distance_con_con(0L, liste_coeur->coord->yabs, liste_coeur->largeur, liste_coeur->layer, 0L,
			     position, plotcon->largeur, plotcon->layer, face);

			if ((liste_coeur->largeur > largeurmin) || (plotcon->largeur > largeurmin)) {
				/*
if (mode_debug) printf("confacecoeur coordcon %ld coordconprec %ld largcon %ld largconprec %ld dist %ld\n",
coordcon,coordconprec,largcon,largconprec,dist); 
*/

				if (dist < dminmetalmetal) {
					ajout_visavis(lst_equipo, liste_coeur, ((plotcon->con_lo)->SIG)->INDEX);
					if ((plotcon->nom_con != eq_vdd) && (plotcon->nom_con != eq_vss))
						return(1);
					/* pas de deport s'il s'agit d'une alim, on continue a parcourir */
				}
			}  else				 {
				if (dist < pitch) {
					ajout_visavis(lst_equipo, liste_coeur, ((plotcon->con_lo)->SIG)->INDEX);
					return(1);  /* deport a faire */
				}
			} /*  fin  */

			liste_coeur = liste_coeur->suiv;
		}

		return(0); /* Pas d'ringerreur c'est lesieur */

		break;

	}

}

/*--------------------------------------------------------------------------------*/
/* Calcul du nombre de cycles avec la liste des visavis des equipo
   Prevoir liberation des ptype liste allouees.                              */

int	calcul_nbdeport_cyclesface(lst_equipo)
LST_EQUIPO lst_equipo;
{
	int	nbdeport = 0;
	ptype_list * liste;

	while (lst_equipo != NULL) {
		liste = lst_equipo->lst_visavis;

		while (liste != NULL) {
			if (existe_visavis(lst_equipo->index, liste->TYPE, lst_equipo)) {
				nbdeport++;
			}

			liste = liste->NEXT;
		}
		lst_equipo = lst_equipo->suiv;
	}

	if (mode_debug) 
		printf("Nb deports cycles trouves %d\n", nbdeport);

	return(nbdeport);
}

/*---------------------------------------------------------------------------------*/
/* Calcul du nombre de deports possibles engendres par le placement de la barre */

int	calcul_nbdeport_equipo_alim(lst_equipo, barrecourant, face)
LST_EQUIPO lst_equipo;
long	barrecourant;
int	face;
{
	LST_EQUIPO equipo_vdd, equipo_vss;
	LST_PSEUDO_CON con;
	chain_list     * ptvdd = NULL , *ptvss = NULL,  *ptcour;
	int	nbdeport = 0, bonus , malus;

	recherche_equipo_alim(&equipo_vdd, &equipo_vss, lst_equipo);

	ptvdd = equipo_vdd->lst_con;
	ptvss = equipo_vss->lst_con;

	/* trt des equipo vdd */

	if (mode_debug) 
		printf("trt eq VDD\n");
	ptcour = ptvdd;

	while (ptcour != NULL) {
		con = (LST_PSEUDO_CON) ptcour->DATA;

		if ((bonus = croisement_con(ptcour, ptvdd, barrecourant, face)) != 0) {
			if (mode_debug) 
				printf("bonus con %s de %d\n", con->nom_con, bonus);
			nbdeport -= (bonus / pitch) ;
		}

		if ((malus = croisement_con(ptcour, ptvss, barrecourant, face)) != 0) {
			if (mode_debug) 
				printf("malus con %s de %d\n", con->nom_con, ((vdd_width / pitch) + (vdd_width % pitch)));
			nbdeport += ((vdd_width / pitch) + (vdd_width % pitch)) ;
		}

		ptcour = ptcour->NEXT;
	}

	/* trt des equipo vss */

	ptcour = ptvss;

	if (mode_debug) 
		printf("trt eq VSS\n");

	while (ptcour != NULL) {
		con = (LST_PSEUDO_CON) ptcour->DATA;

		bonus = croisement_con(ptcour, ptvss, barrecourant, face);

		if (bonus != 0) {
			if (mode_debug) 
				printf("bonus con %s de %d\n", con->nom_con, bonus);
			nbdeport -= (bonus / pitch) ;
		}

		ptcour = ptcour->NEXT;
	}

	if (mode_debug) 
		printf("Nb deports total alim %d \n", nbdeport);

	return(nbdeport);
}

/*--------------------------------------------------------------------------------*/

/* Parcours de la liste des connecteurs d'alim pour voir s'il existe des vis
   a vis. Si aucun vis a vis retour 0, sinon retour du croisement des 2
   connecteurs                                                                    */

int	croisement_con(ptcour, ptalim, barrecourant, face)
chain_list *ptcour;
chain_list *ptalim;
long	barrecourant;
int	face;
{

	LST_PSEUDO_CON con, concour;
	long	position, positioncour, dminmetalmetal, diff;

	concour = (LST_PSEUDO_CON) ptcour->DATA;

	/*
if (mode_debug) printf("\tCroisement con  %s larg %ld face %d x %ld y %ld\n",concour->nom_con,
concour->largeur,face,(concour->coord)->xabs,(concour->coord)->yabs);
*/

	switch (face) {
	case NORD:
	case SUD :
		positioncour = (concour->coord)->xabs + barrecourant;
		dminmetalmetal = ymetal_dmin;
		break;
	case EST  :
	case OUEST:
		positioncour = (concour->coord)->yabs + barrecourant;
		dminmetalmetal = xmetal_dmin;
		break;
	}

	while (ptalim != NULL) {
		con = (LST_PSEUDO_CON) ptalim->DATA;

		if ((ptalim != ptcour)  && (con->face == face) && (con->coeur_plot != concour->coeur_plot)) {
			switch (face) {
			case NORD:
			case SUD :
				position = (con->coord)->xabs + barrecourant;
				break;
			case EST  :
			case OUEST:
				position = (con->coord)->yabs + barrecourant;
				break;
			}

			/* meme layer car on ne s'en preoccupe pas */

			diff = distance_con_con(position, position, con->largeur, con->layer, positioncour, positioncour,
			     concour->largeur, con->layer, face);

			/*        diff = position - (con->width / 2) - (con->width % 2)
             - (positioncour + (concour->width / 2) + (concour->width % 2));
          Avant simplification */

			if ((diff < 0) || (diff < dminmetalmetal))
				if (mode_debug) 
					printf("\tposition cour %ld nom %s position %ld ***diffcrois %ld larg %ld\n", positioncour,
					     con->nom_con, position, diff, con->largeur);

			if (diff < 0)  
				return((int) -diff);
			if (diff < dminmetalmetal) 
				return ((int) pitch);
		} /* fin du if */

		ptalim = ptalim->NEXT;
	}

	return((int) 0);  /* Aucun croisement trouve */
}

/*-----------------------------------------------------------------------------------*/

/*  procedure qui retourne les equipotentielles d'alim  */

void recherche_equipo_alim(equipo_vdd, equipo_vss, lst_equipo)
LST_EQUIPO *equipo_vdd;
LST_EQUIPO *equipo_vss;
LST_EQUIPO  lst_equipo;
{
	LST_PSEUDO_CON con;

	(*equipo_vdd) = NULL;
	(*equipo_vss) = NULL;

	while (lst_equipo != NULL) {
		if (lst_equipo->type == ALIM) {
			con = (LST_PSEUDO_CON) ((lst_equipo->lst_con)->DATA);

			if (con->nom_con == eq_vdd) 
				(*equipo_vdd) = lst_equipo;
			else 
				(*equipo_vss) = lst_equipo;

			if (((*equipo_vss) != NULL) && ((*equipo_vdd) != NULL))
				break;
		}
		lst_equipo = lst_equipo->suiv;
	}

	if (((*equipo_vss) == NULL) || ((*equipo_vdd) == NULL))
		ringerreur(ERR_MANQUEALIM, NULL);
}

/*-----------------------------------------------------------------------------------*/
/* Verification si les connecteurs d'alim sont dans la face du coeur                 */

int	conplotalim_dans_coeur(lst_equipo, coeur, barrecourant, face)
LST_EQUIPO lst_equipo;
COEUR      coeur;
long	barrecourant;
int	face;
{
	LST_EQUIPO equipo_vdd, equipo_vss;
	LST_PSEUDO_CON con;
	chain_list * liste_vdd;
	chain_list * liste_vss;
	long	alasoupe;

	recherche_equipo_alim(&equipo_vdd, &equipo_vss, lst_equipo);

	liste_vdd = equipo_vdd->lst_con;
	liste_vss = equipo_vss->lst_con;

	if (mode_debug) 
		printf("barrecourant %ld coeurheight %ld coeurwidth %ld\n", barrecourant, coeur.height, coeur.width);

	while (liste_vdd != NULL) {
		con = (LST_PSEUDO_CON) liste_vdd->DATA;
		if ((con->coeur_plot == PLOT_CON) && (con->face == face))

			switch (con->face) {
			case NORD:
			case SUD :
				if (((barrecourant + con->coord->xabs - con->largeur / 2) < (coeur.coord).xabs) ||  ((barrecourant +
				    con->coord->xabs + con->largeur / 2) > ((coeur.coord).xabs + coeur.width)))
					return(0); /* le connecteur n'est pas en face du coeur */

				break;

			case EST  :
			case OUEST:
				alasoupe =  ((barrecourant + con->coord->yabs - con->largeur / 2));
				if (mode_debug) 
					printf("binf %ld\t", alasoupe);
				alasoupe =  ((barrecourant + con->coord->yabs + con->largeur / 2));
				if (mode_debug) 
					printf("bsup %ld\t", alasoupe);

				if (mode_debug) 
					printf("plot %s coord x %ld y %ld larg %ld\n", con->nom_con, con->coord->xabs, con->coord->yabs,
					     con->largeur);
				if (((barrecourant + con->coord->yabs - con->largeur / 2) < (coeur.coord).yabs) ||  ((barrecourant +
				    con->coord->yabs + con->largeur / 2) > ((coeur.coord).yabs + coeur.height)))
					return(0); /* le connecteur n'est pas en face du coeur */

				break;
			}
		liste_vdd = liste_vdd->NEXT;
	}

	while (liste_vss != NULL) {
		con = (LST_PSEUDO_CON) liste_vss->DATA;
		if ((con->coeur_plot == PLOT_CON) && (con->face == face))

			switch (con->face) {
			case NORD:
			case SUD :
				if (((barrecourant + con->coord->xabs - con->largeur / 2) < (coeur.coord).xabs) ||  ((barrecourant +
				    con->coord->xabs + con->largeur / 2) > ((coeur.coord).xabs + coeur.width)))
					return(0); /* le connecteur n'est pas en face du coeur */

				break;

			case EST  :
			case OUEST:
				alasoupe =  ((barrecourant + con->coord->yabs - con->largeur / 2));
				if (mode_debug) 
					printf("binf %ld\t", alasoupe);
				alasoupe =  ((barrecourant + con->coord->yabs + con->largeur / 2));
				if (mode_debug) 
					printf("bsup %ld\t", alasoupe);

				if (mode_debug) 
					printf("plot %s coord x %ld y %ld larg %ld\n", con->nom_con, con->coord->xabs, con->coord->yabs,
					     con->largeur);
				if (((barrecourant + con->coord->yabs - con->largeur / 2) < (coeur.coord).yabs) ||  ((barrecourant +
				    con->coord->yabs + con->largeur / 2) > ((coeur.coord).yabs + coeur.height)))
					return(0); /* le connecteur n'est pas en face du coeur */

				break;
			}
		liste_vss = liste_vss->NEXT;
	}

	/* ningun problema */
	return(1);

}

/*--------------------------------------------------------------------------------*/
/* Apres le placement de la barre de plots, on mets a jour les coordonnes des
   connecteurs                                                                    */

void maj_coordplots(tab_plots, lst_equipo)
BARRE_PLOTS    tab_plots[NB_FACES];
LST_EQUIPO     lst_equipo;
{
	LST_EQUIPO     liste_eq = lst_equipo;
	LST_PSEUDO_CON liste;
	int	face;
	char	niveau;
	long	position, largeurmin, largeurmax;

	if (WVIA_ALU1 > WVIA_ALU2) 
		largeurmax = WVIA_ALU1 * lambda;
	else 
		largeurmax = WVIA_ALU2 * lambda;

	if (mode_debug) 
		printf("Largeurmax = %ld\n", largeurmax);

	/* Mise a nulle des listes de vis a vis des equipo */
	while (liste_eq) {
		liste_eq->lst_visavis = NULL; /* prevoir desallocation */
		liste_eq = liste_eq->suiv;
	}

	for (face = 0; face < NB_FACES; face++) {
		liste = tab_plots[face].lst_con;

		if (mode_debug) 
			printf("Face %d\n", face);

		switch (face) {

		case NORD:
		case SUD :
			niveau = ymetal;
			largeurmin = ymetal_width;

			while (liste != NULL) {
				if (mode_debug) 
					printf("\t%s width = %ld\n", liste->nom_con, liste->largeur);

				if ((liste->nom_con != eq_vdd) && (liste->nom_con != eq_vss) && (liste->largeur > largeurmax)) 
					ringerreur(ERR_CONLARGEUR, liste);

				switch (liste->layer) {
				case ALU1: 
					if (liste->largeur < WMIN_ALU1) /* ringerreur largeur connecteur */
						ringerreur(ERR_CONLARGEUR, liste);
					break;
				case ALU2: 
					if (liste->largeur < WMIN_ALU2) /* ringerreur largeur connecteur */
						ringerreur(ERR_CONLARGEUR, liste);
					break;
				default :  
					ringerreur(ERR_CONLARGEUR, liste);
				}

				position = (liste->coord)->xabs + (tab_plots[face].coord).xabs;
				(liste->coord)->xabs = position;
				(liste->coord)->yabs = tab_plots[face].coord.yabs;
				(liste->coord)->piste = (tab_plots[face].coord).piste;

				if (mode_debug) 
					printf("position %ld du connecteur %s face %d\n", position, liste->nom_con, face);

				liste = liste->suiv;
			}  /* fin du while */
			break;

		case EST  :
		case OUEST:
			niveau = xmetal;
			largeurmin = xmetal_width;

			while (liste != NULL) {
				if (mode_debug) 
					printf("\t%s width=%ld y %ld ybarre %ld \n", liste->nom_con, liste->largeur, liste->coord->yabs,
					     tab_plots[face].coord.yabs);

				if ((liste->nom_con != eq_vdd) && (liste->nom_con != eq_vss) && (liste->largeur > largeurmax)) 
					ringerreur(ERR_CONLARGEUR, liste);

				switch (liste->layer) {
				case ALU1: 
					if (liste->largeur < WMIN_ALU1) /* ringerreur largeur connecteur */
						ringerreur(ERR_CONLARGEUR, liste);
					break;
				case ALU2: 
					if (liste->largeur < WMIN_ALU2) /* ringerreur largeur connecteur */

						ringerreur(ERR_CONLARGEUR, liste);
					break;
				default :  
					ringerreur(ERR_CONLARGEUR, liste);
				}

				position = (liste->coord)->yabs + (tab_plots[face].coord).yabs;
				(liste->coord)->yabs = position;
				(liste->coord)->xabs = (tab_plots[face].coord).xabs;
				(liste->coord)->piste = (tab_plots[face].coord).piste;

				if (mode_debug) 
					printf("position %ld du connecteur %s face %d\n", position, liste->nom_con, face);

				liste = liste->suiv;
			}  /* fin du while */
			break;
		} /* fin du switch */

	} /* fin du for */
}

/*----------------------------------------------------------------------------*/

/* Fabrication de la grille finale a partir des connecteurs de plots.
   Verification de la distance des connecteurs entre eux leur largeur 
   Mise a jour des futurs deports.

  Rq: la dmin a1 a1 est de 3 cad 30 avec le SCALE_X actuel, pour faire les nouveaux 
  pas de grille, on se sert de dmin/2, mais les pas doivent etre multiples de 
  scale_x, donc pour les calculs des nouveaux pas on prend
  ((pos + scale_x/2) /scale_x) *scale_x 
                                                                              */

void fabrique_grille_finale(tab_plots, tab_coeur, lecoeur, lst_equipo, tab_grilles)
BARRE_PLOTS    tab_plots[NB_FACES];
LST_PSEUDO_CON tab_coeur[NB_FACES];
COEUR          lecoeur;
LST_EQUIPO     lst_equipo;
GRILLE         tab_grilles[NB_FACES];
{
	LST_PSEUDO_CON liste, liste_coeur;
	int	face;
	char	niveau;
	long	position, largeurmin;

	if (mode_debug) 
		printf("Fabrique grille finale\n");
	if (mode_debug) 
		printf("Coord coeur x%ld y%ld w%ld h%ld\n", lecoeur.coord.xabs, lecoeur.coord.yabs, lecoeur.width, lecoeur.height);

	for (face = 0; face < NB_FACES; face++) {
		liste = tab_plots[face].lst_con;
		liste_coeur = tab_coeur[face];

		if (mode_debug) 
			printf("Face %d\n", face);

		switch (face) {
		case NORD:
		case SUD :
			niveau = ymetal;
			largeurmin = ymetal_width;

			while (liste != NULL) {
				if (mode_debug) 
					printf("\t%s\n", liste->nom_con);

				if (moins_dun_pitch_preccon(liste))
					ringerreur(ERR_CONDISTANCE, liste);

				position = (liste->coord)->xabs;

				if (mode_debug) 
					printf("position %ld du connecteur %s face %d\n", position, liste->nom_con, face);

				if ((liste->nom_con != eq_vdd) && (liste->nom_con != eq_vss)) {
					/* en dehors du coeur = deport */

					if (position < (lecoeur.coord).xabs) {
						if (mode_debug) 
							printf("Deportg connecteur %s %ld\n", liste->nom_con, position);
						alloue_coord(0L, 0, &(liste->deport));
						/*           liste->deport = (PT_COORDONNEES) mbkalloc ((unsigned int) sizeof(COORDONNEES)); */

						(liste->deport)->piste = 0; /* deport uniquement pour differencier du layer */

						ajout_coordonnees_grille(liste->coord, &(tab_grilles[face].lst_deportg),
						    face);
					} else if (position > ((lecoeur.coord).xabs + lecoeur.width)) {
						if (mode_debug) 
							printf("Deportd connecteur %s %ld\n", liste->nom_con, position);
						alloue_coord(0L, 0, &(liste->deport));
						/*           liste->deport = (PT_COORDONNEES) mbkalloc ((unsigned int) sizeof(COORDONNEES)); */

						(liste->deport)->piste = 0; /* deport uniquement pour differencier du layer */

						ajout_coordonnees_grille(liste->coord, &(tab_grilles[face].lst_deportd),
						    face);
					}  else if (moins_dun_pitch_confacecoeur(position, liste, liste_coeur, lst_equipo,
					     face)) { /* Ne forme pas un nouveau pas de grille */
						if (mode_debug) 
							printf("Deport connecteur %s\n", liste->nom_con);
						alloue_coord(0L, 0, &(liste->deport));
						/*           		liste->deport = (PT_COORDONNEES) mbkalloc ((unsigned int) sizeof(COORDONNEES)); */

						(liste->deport)->piste = 0; /* deport uniquement pour differencier du layer */
					} else
					 {
						if (mode_debug) 
							printf("Nouveau pas connecteur %s %ld\n", liste->nom_con, position);

						ajout_coordonnees_grille(liste->coord, &(tab_grilles[face].lst_pas), face);
					}

				} /* fin du if  */  else
				 { /* Il s'agit d'un plot d'alimentation, c'est un pas obligatoire de la grille */

					/* si ringerreur ici => ringerreur dans le placement de la barre de plot! */

					if (position < (lecoeur.coord).xabs) 
						ringerreur(ERR_BARREALIM, (void * ) & face);
					if (position > ((lecoeur.coord).xabs + lecoeur.width)) 
						ringerreur(ERR_BARREALIM, (void * ) & face);

					moins_dun_pitch_confacecoeur(position, liste, liste_coeur, lst_equipo, face);
					if (mode_debug) 
						printf("Nouveau pas ALIM connecteur %s %ld\n", liste->nom_con, position);

					ajout_coordonnees_grille(liste->coord, &(tab_grilles[face].lst_pas), face);
				}

				liste = liste->suiv;
			}  /* fin du while */
			break;

		case EST  :
		case OUEST:
			niveau = xmetal;
			largeurmin = xmetal_width;

			while (liste != NULL) {
				if (mode_debug) 
					printf("\t%s y %ld ybarre %ld \n", liste->nom_con, liste->coord->yabs, tab_plots[face].coord.yabs);

				if (moins_dun_pitch_preccon(liste))
					ringerreur(ERR_CONDISTANCE, liste);

				position = (liste->coord)->yabs;
				if (mode_debug) 
					printf("position %ld du connecteur %s face %d\n", position, liste->nom_con, face);

				if ((liste->nom_con != eq_vdd) && (liste->nom_con != eq_vss)) {
					/* en dehors du coeur = deport */

					if (position < (lecoeur.coord).yabs) {
						if (mode_debug) 
							printf("Deport connecteur %s %ld\n", liste->nom_con, position);
						alloue_coord(0L, 0, &(liste->deport));
						/*           liste->deport = (PT_COORDONNEES) mbkalloc ((unsigned int) sizeof(COORDONNEES)); */
						(liste->deport)->piste = 0; /* deport uniquement pour differencier du layer */

						ajout_coordonnees_grille(liste->coord, &(tab_grilles[face].lst_deportg),
						    face);
					} else if (position > ((lecoeur.coord).yabs + lecoeur.height)) {
						if (mode_debug) 
							printf("Deport connecteur %s %ld\n", liste->nom_con, position);
						alloue_coord(0L, 0, &(liste->deport));
						/*           liste->deport = (PT_COORDONNEES) mbkalloc ((unsigned int) sizeof(COORDONNEES)); */
						(liste->deport)->piste = 0; /* deport uniquement pour differencier du layer */

						ajout_coordonnees_grille(liste->coord, &(tab_grilles[face].lst_deportd),
						    face);
					}  else if (moins_dun_pitch_confacecoeur(position, liste, liste_coeur, lst_equipo,
					     face)) {
						if (mode_debug) 
							printf("Deport connecteur %s %ld\n", liste->nom_con, position);
						alloue_coord(0L, 0, &(liste->deport));
						/*           liste->deport = (PT_COORDONNEES) mbkalloc ((unsigned int) sizeof(COORDONNEES)); */
						(liste->deport)->piste = 0; /* deport uniquement pour differencier du layer */
					} else
					 {
						if (mode_debug) 
							printf("Nouveau pas connecteur %s %ld\n", liste->nom_con, position);

						ajout_coordonnees_grille(liste->coord, &(tab_grilles[face].lst_pas), face);
					}

				} /* fin du if */ else
				 { /* Il s'agit d'un plot d'alimentation, c'est un pas obligatoire de la grille */

					/* si ringerreur ici => ringerreur dans le placement de la barre de plot! */

					if (position < (lecoeur.coord).yabs) 
						ringerreur(ERR_BARREALIM, (void * ) & face);
					if (position > ((lecoeur.coord).yabs + lecoeur.height)) 
						ringerreur(ERR_BARREALIM, (void * ) & face);

					moins_dun_pitch_confacecoeur(position, liste, liste_coeur, lst_equipo, face);
					if (mode_debug) 
						printf("Nouveau pas ALIM connecteur %s %ld\n", liste->nom_con, position);

					ajout_coordonnees_grille(liste->coord, &(tab_grilles[face].lst_pas), face);
				}

				liste = liste->suiv;
			} /* fin du while */

			break;
		}  /* Fin du switch() */

		/*------------- AJOUT DE PAS SUPPLEMENTAIRES SI DIST ENTRE PAS >= 2 PITCH --------*/

		ajout_pas_grille(tab_grilles, lecoeur, face);

	} /* fin du for */
}

/*------------------------------------------------------------------------------------*/

/* Ajout de nouveaux pas de grille si distance entre connecteur est suffisante */
/*
  Rq: la dmin a1 a1 est de 3 cad 30 avec le SCALE_X actuel, pour faire les nouveaux 
  pas de grille, on se sert de dmin/2, mais les pas doivent etre multiples de 
  scale_x, donc pour les calculs des nouveaux pas on prend pour a1 ou a2
  ((pos + scale_x) /scale_x) *scale_x     
  ceci est utilise quand connecteurs de largeur non standard sinon pas de pb          */

/* bug corrige au niveau des calculs de pas (+lamda / lambda * lambda) */
/* 13 sept 92: autre bug corrige.
   Les connecteurs d'alim peuvent etre en vis a vis et se recouvrir, ce qui
   faisait creer des nouveaux pas dans les alim !
   Les fonctions existe_con_prec 	et existe_con_suiv trouve le 
   connecteur le plus proche de celui qu'on cherche, donc une alim 
   recouvrant si elle existe, et repousse les nouveaux pas dans une
   zone de routage vraiment libre. */
/* Attention: Le reglage pour les pas de grille est tres precis! 
   si modif, verifier a la main qu'on respecte les distances ds ts les cas ! */

void ajout_pas_grille(tab_grilles, lecoeur, face)
GRILLE tab_grilles[NB_FACES];
COEUR  lecoeur;
int	face;
{
	PT_COORDONNEES coordalim, nouveau, c1, c2, liste_coor;
	long	np, enleve, coordcon, coordconprec, largcon, largconprec;
	long	debut1, fin1, dist, largeurmin, dminmetalmetal;
	char	layercon, layerconprec;

	if (mode_debug) 
		printf("FACE a completer %d\n", face);

	liste_coor = tab_grilles[face].lst_pas;

	/* pour les vias */

	if (ymetal_dmin > xmetal_dmin) 
		dminmetalmetal = ymetal_dmin;
	else 
		dminmetalmetal = xmetal_dmin;

	/*------------------ DEBUT DE GRILLE ----------------------------------------*/
	if (liste_coor != NULL)
		switch (face) {
		case NORD :
		case SUD  : 
			if (mode_debug) 
				printf("1er coordonnee %ld\n", liste_coor->xabs);
			largeurmin = ymetal_wvia;

			/* on recherche si alim suivante recouvrant connecteur  existe */
			liste_coor = existe_con_suiv(0L, 0L, ymetal_width, ymetal, face, tab_grilles[face].lst_pas);
			if (NULL == liste_coor) 
				ringerreur(ERR_GRILLEINTERNE, NULL, NULL);

			if (mode_debug) 
				printf("1ER CONNECTEUR x %ld y %ld face %d\n\n", liste_coor->xabs, liste_coor->yabs, face);

			if (((LST_PSEUDO_CON)liste_coor->proprio)->largeur > largeurmin) {
				enleve = ((LST_PSEUDO_CON)liste_coor->proprio)->largeur / 2 + dminmetalmetal + taille_via /
				    2;
				if (((LST_PSEUDO_CON)liste_coor->proprio)->largeur < taille_via)
					enleve += ( taille_via / 2 - ((LST_PSEUDO_CON)liste_coor->proprio)->largeur / 2);

				enleve = ((enleve + lambda) / lambda) * lambda;
			} else 
				enleve = pitch;

			for (np = (lecoeur.coord).xabs + pitch; np <= (liste_coor->xabs - enleve); np = np + pitch) {
				/* ce for calcule les nouveaux pas de grille */
				alloue_coord(np, face, &nouveau);
				ajout_coordonnees_grille(nouveau, &(tab_grilles[face].lst_pas), face);
			}
			break;
		case EST  :
		case OUEST:
			if (mode_debug) 
				printf("1er coordonnee %ld\n", liste_coor->yabs);
			largeurmin = xmetal_wvia;

			/* on recherche si alim suivante recouvrant connecteur  existe */
			liste_coor = existe_con_suiv(0L, 0L, xmetal_width, xmetal, face, tab_grilles[face].lst_pas);
			if (NULL == liste_coor) 
				ringerreur(ERR_GRILLEINTERNE, NULL, NULL);

			if (mode_debug) 
				printf("1ER CONNECTEUR x %ld y %ld face %d\n\n", liste_coor->xabs, liste_coor->yabs, face);

			if (((LST_PSEUDO_CON)liste_coor->proprio)->largeur > largeurmin) {
				enleve = ((LST_PSEUDO_CON)liste_coor->proprio)->largeur / 2 + dminmetalmetal + taille_via /
				    2;
				if (((LST_PSEUDO_CON)liste_coor->proprio)->largeur < taille_via)
					enleve += ( taille_via / 2 - ((LST_PSEUDO_CON)liste_coor->proprio)->largeur / 2);

				enleve = ((enleve + lambda) / lambda) * lambda;
			} else 
				enleve = pitch;

			for (np = (lecoeur.coord).yabs + pitch; np <= (liste_coor->yabs - enleve); np = np + pitch) {
				/* ce for calcule les nouveaux pas de grille */
				alloue_coord(np, face, &nouveau);
				ajout_coordonnees_grille(nouveau, &(tab_grilles[face].lst_pas), face);
			}
			break;
		}

	/*------------------------- GRILLE COURANTE --------------------------------*/

	if (mode_debug) 
		printf("Grille courante\n\n");

	while ((liste_coor != NULL) && (liste_coor->suiv != NULL)) {
		c1 = liste_coor; 
		c2 = liste_coor->suiv;

		switch (face) {
		case NORD:
		case SUD :
			if (mode_debug) 
				printf("grille courante 1er %ld\n", liste_coor->xabs);
			coordcon = c2->xabs;
			coordconprec = c1->xabs;
			break;
		case EST  :
		case OUEST:
			coordcon = c2->yabs;
			coordconprec = c1->yabs;
			break;
		}

		largcon      = ((LST_PSEUDO_CON)c2->proprio)->largeur;
		layercon      = ((LST_PSEUDO_CON)c2->proprio)->layer;
		largconprec  = ((LST_PSEUDO_CON)c1->proprio)->largeur;
		layerconprec  = ((LST_PSEUDO_CON)c1->proprio)->layer;

		dist = distance_con_con(coordcon, coordcon, largcon, layercon, coordconprec, coordconprec, largconprec, layerconprec,
		     face);
		/* on recherche si alim precedente recouvrant connecteur precedent existe */
		coordalim = existe_con_precalim(coordcon, coordcon, largcon, layercon, face, tab_grilles[face].lst_pas, dist);

		if (NULL != coordalim) {
			if (mode_debug) 
				printf("RECOUVRE TROUVE x %ld y %ld coordcon x %ld y %ld face %d DIST= %ld\n\n", coordalim->xabs,
				     coordalim->yabs, coordcon, coordcon, face, dist);
			if ((NORD == face) || (SUD == face)) 
				coordconprec = coordalim->xabs;
			else 
				coordconprec = coordalim->yabs;
			largconprec  = ((LST_PSEUDO_CON)coordalim->proprio)->largeur;
			layerconprec  = ((LST_PSEUDO_CON)coordalim->proprio)->layer;
		}

		dist = distance_con_con(coordcon, coordcon, largcon, layercon, coordconprec, coordconprec, largconprec, layerconprec,
		     face);

		if ((largcon > largeurmin) || (largconprec > largeurmin)) {
			if (mode_debug) 
				printf("largeur non standard\n %ld %ld", largconprec, largcon);

			if (largconprec <= largeurmin) 
				debut1 = pitch;
			else
			 { 
				debut1 = largconprec / 2 + dminmetalmetal + taille_via / 2;
				if (largconprec < taille_via) 
					debut1 += (taille_via / 2 - largconprec / 2);
				debut1 = ((debut1 + lambda) / lambda) * lambda;
			}

			if (largcon <= largeurmin) 
				fin1 = pitch;
			else
			 {
				fin1 = largcon / 2 + dminmetalmetal + taille_via / 2;
				if (largcon < taille_via) 
					fin1 += (taille_via / 2 - largcon / 2);

				fin1 = ((fin1 + lambda) / lambda) * lambda;

			}

			if (dist >= (2 * dminmetalmetal + largeurmin))
				for (np = coordconprec + debut1; np <=  (coordcon - fin1); np = np + pitch) {
					/* ce for costaud calcule les nouveaux pas de grille */
					alloue_coord(np, face, &nouveau);
					ajout_coordonnees_grille(nouveau, &(tab_grilles[face].lst_pas), face);
				}
		} else
		 {
			if (dist >= (2 * pitch))
				for (np = coordconprec + pitch; np <= (coordcon - pitch); np = np + pitch) {
					alloue_coord(np, face, &nouveau);
					ajout_coordonnees_grille(nouveau, &(tab_grilles[face].lst_pas), face);
				}
		}

		/* Si on a inserer de nouveaux elements il faut pas les traiter donc on prend c2 comme
     pas suivant */
		liste_coor = c2;
	} /*fin du while */

	if (liste_coor != NULL) {
		/*------------------------------- FIN DE GRILLE ----------------------------*/
		switch (face) {
		case NORD :
		case SUD  :
			/* on recherche si alim suivante recouvrant connecteur  existe */
			liste_coor = existe_con_suiv(lecoeur.width + lecoeur.coord.xabs, lecoeur.height + lecoeur.coord.yabs,
			     			 ymetal_width, ymetal, face, tab_grilles[face].lst_pas);
			if (NULL == liste_coor) 
				ringerreur(ERR_GRILLEINTERNE, NULL, NULL);

			if (mode_debug) 
				printf("Fin de grille dernier %ld\n", liste_coor->xabs);

			if (((LST_PSEUDO_CON)liste_coor->proprio)->largeur > largeurmin) {
				enleve = ((LST_PSEUDO_CON)liste_coor->proprio)->largeur / 2 + dminmetalmetal + taille_via /
				    2;
				if (((LST_PSEUDO_CON)liste_coor->proprio)->largeur < taille_via)
					enleve += ( taille_via / 2 - ((LST_PSEUDO_CON)liste_coor->proprio)->largeur / 2);

				enleve = ((enleve + lambda) / lambda) * lambda;
			} else 
				enleve = pitch;

			for (np = liste_coor->xabs + enleve; np <= ((lecoeur.coord).xabs + lecoeur.width - pitch); np = np +
			    pitch) {
				/* ce for calcule les nouveaux pas en fin de grille */
				alloue_coord(np, face, &nouveau);
				ajout_coordonnees_grille(nouveau, &(tab_grilles[face].lst_pas), face);
			}
			break;
		case EST  :
		case OUEST:
			/* on recherche si alim suivante recouvrant connecteur  existe */
			liste_coor = existe_con_suiv(lecoeur.width + lecoeur.coord.xabs, lecoeur.height + lecoeur.coord.yabs,
			     			 xmetal_width, xmetal, face, tab_grilles[face].lst_pas);
			if (NULL == liste_coor) 
				ringerreur(ERR_GRILLEINTERNE, NULL, NULL);

			if (mode_debug) 
				printf("Fin de grille dernier %ld\n", liste_coor->yabs);

			if (((LST_PSEUDO_CON)liste_coor->proprio)->largeur > largeurmin) {
				enleve = ((LST_PSEUDO_CON)liste_coor->proprio)->largeur / 2 + dminmetalmetal + taille_via /
				    2;
				if (((LST_PSEUDO_CON)liste_coor->proprio)->largeur < taille_via)
					enleve += ( taille_via / 2 - ((LST_PSEUDO_CON)liste_coor->proprio)->largeur / 2);

				enleve = ((enleve + lambda) / lambda) * lambda;
			} else 
				enleve = pitch;

			for (np = liste_coor->yabs + enleve; np <= ((lecoeur.coord).yabs + lecoeur.height - pitch); np =
			    np + pitch) {
				/* ce for calcule les nouveaux pas en fin de grille */
				alloue_coord(np, face, &nouveau);
				ajout_coordonnees_grille(nouveau, &(tab_grilles[face].lst_pas), face);
			}
			break;
		}

	} /* fin du if != NULL */

}

/*---------------------------------------------------------------------*/
/* Cette procedure relie les plots eloignes par fabrique_barre avec la liste
   lst_conestouest, cad relie les alim internes faces ouest et est            */

void relier_plots_wire1(lastinst, lastinst2, lst)
phins_list *lastinst, *lastinst2;
chain_list *lst;
{
	phcon_list * con1, *con2;

	while (NULL != lst) {
		con2 = (phcon_list * ) lst->DATA;
		con1 = (phcon_list * ) lst->NEXT->DATA;

		poser_wire1(ALU2, con1->WIDTH / SCALE_X, lastinst->INSNAME, con1->NAME, con1->INDEX, lastinst2->INSNAME,
		    con2->NAME, con2->INDEX);

		lst = lst->NEXT->NEXT;
	}

}

