/****************************************************************************/
/*                                                                          */
/*                      Chaine de CAO & VLSI   Alliance                     */
/*                                                                          */
/*    Produit : ring router                                                 */
/*    Fichier : lireplace.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 29 avril 92 ----------------------------------- LIREPLACE.C            */
/* PHASE 3 */

/* Lecture du fichier de placement afin de connaitre les plots, leur orientation,
   ainsi que les signaux de largeur specifique.
	
   Pour la lecture et l'interpretation du fichier les outils lex et yacc sont
   utilises */

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

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

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

/* Lecture et verification du fichier de parametres , suffixe .rin. Lancement de
   l'analyseur syntaxique                                                         */

void lecture_fic(nomfic, circuit_lo, lecoeur, nb_inst_plots)
char	*nomfic;
lofig_list  *circuit_lo;
COEUR       lecoeur;
int	nb_inst_plots;

{
	FILE * fichier;
	long	longueur;
	chain_list * liste;
	int	i, cpt_liste = 0, cpt_plots = 0, larg_con;
	char	*nom_du_plot, *nom_con;
	loins_list * ptinst;

	/* Ouverture et verification du fichier de parametre (existence et longueur) */

	if ((fichier = mbkfopen(nomfic, NULL, READ_TEXT)) == NULL) 
		ringerreur(ERR_FICPARAM, nomfic);

	if (fseek(fichier, (long)0, SEEK_END))   
		ringerreur(ERR_FICPARAM, nomfic);

	if ((longueur = ftell(fichier)) == -1)     
		ringerreur(ERR_FICPARAM, nomfic);

	if (longueur == 0)                       
		ringerreur(ERR_VIDEFICPARAM, nomfic);

	fclose(fichier);

	if (mode_debug) 
		printf("Longueur fichier parametres: %ld\n", longueur);

	for (i = 0; i < NB_FACES; i++)
		nom_plot[i] = NULL;

	liste_width = NULL;                 /* Initialisations des listes globales utilisees
	                                       par lex et yacc */

	if (mode_debug) 
		printf("Avant analyse lex et yacc \n");

	yyin = mbkfopen(nomfic, NULL, READ_TEXT);

	/* lancement de lex et yacc pour interpreter le fichier de parametres */

	yyparse();
	if (mode_debug) 
		printf("Apres analyse lex et yacc\n");

	/* inversion des listes pour respecter l'ordre du placement des plots */
	/* verification de la coherence des informations receuillies */

	for (i = 0; i < NB_FACES; i++) {
		nom_plot[i] = reverse(nom_plot[i]);
		if (nom_plot[i] != NULL) 
			cpt_liste++;
	}

	if (!cpt_liste) 
		ringerreur(ERR_AUCUNPLOTPARAM, NULL);

	/* parcours des noms d'instances des plots et verif si existent ds circuit_lo */

	for (i = 0; i < NB_FACES; i++) {
		if (mode_debug) 
			printf("---------numero face :%d\n", i);

		liste = nom_plot[i];

		/* De part la modification des chain_list de nom_plot, je verifie d'abord sur 
     l'ancienne structure (noms uniquement) qu'il y a une seule occurrence */

		while (liste != NULL) {
			nom_du_plot = (char *)(liste->DATA);
			if (mode_debug) 
				printf("VERIF nom plot: --%s--\n", nom_du_plot);

			/* une seule occurence dans la liste des faces de plots */

			if (!uneseuleoccurence(nom_du_plot, nom_plot))
				ringerreur(ERR_PLUSPLOTPARAM, nom_du_plot);

			liste = liste->NEXT;
		}

		liste = nom_plot[i];

		while (liste != NULL) {
			nom_du_plot = (char *)(liste->DATA);
			if (mode_debug) 
				printf("VERIF nom plot: --%s--\n", nom_du_plot);

			/* existence  du plot dans la liste du circuit logique */

			if ((ptinst = existe_plot_circuit(nom_du_plot, circuit_lo)) == NULL)
				ringerreur(ERR_NONPLOTPARAM, nom_du_plot);

			else /* Chain_list modifiee pointe maintenant sur l'instance logique */
				liste->DATA = (void * ) ptinst;

			cpt_plots++;

			liste = liste->NEXT;
		}
	}

	if (cpt_plots != nb_inst_plots)
		ringerreur(ERR_NBPLOTPARAM, circuit_lo);

	liste = liste_width;
	if (mode_debug) 
		printf("VERIF Liste width\n");

	/* verification sur la liste des connecteurs de largeur specifique */

	while (liste != NULL) {
		nom_con  = ((PTCEL)(liste->DATA))->chaine;
		larg_con = ((PTCEL)(liste->DATA))->largeur;
		if (mode_debug) 
			printf("Connecteur --%s-- largeur %ld\n", nom_con, larg_con);

		/* existence  du connecteur dans la liste des connecteurs logiques du circuit */
		if (!existe_signal_circuit(liste, circuit_lo, lecoeur))
			ringerreur(ERR_NONCONWIDTHPARAM, nom_con);

		if (larg_con < SCALE_X) 
			ringerreur(ERR_WIDTHPARAM, (void * )nom_con, (void * ) & larg_con);

		liste = liste->NEXT;
	}

}

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

/* Erreur dans la syntaxe du fichier de parametre */
yyerror(s)
char	*s;
{
	ringerreur(ERR_SYNPARAM, 1);
}

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

/* Fabrication de la liste des equipotentielles a partir de la vue logique du coeur
   et circuit */

void fabrique_equipo(nomplot, lecoeur, lst_equipo)
chain_list *nomplot[NB_FACES];
COEUR      lecoeur;
LST_EQUIPO *lst_equipo;
{

	locon_list * pt_coeur, *tete_coeur, *con_coeur = (lecoeur.coeur_lo)->LOCON ;
	locon_list * con_plot, *liste_con, *liste_con2;
	losig_list * sig_coeur;
	loins_list * plot, *plot2;
	int	face, i, j,  signal_ok;
	chain_list * liste_plots, *liste_plots2;
	LST_EQUIPO liste, pt_eq;

	(*lst_equipo) = NULL;

	if (mode_debug) 
		printf("Fabrication des equipo\n");

	/* boucle des locon du coeur */

	while (con_coeur != NULL) {
		sig_coeur = con_coeur->SIG;  /* un signal unique par connecteur */
		if (mode_debug) 
			printf("pointeur Sigcoeur %d\n", (int) sig_coeur);
		if (mode_debug) 
			printf("*******NOM concoeur %s signal %ld*********\n", con_coeur->NAME, sig_coeur->INDEX);

		/* Parcours des instances plots */

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

			liste_plots = nomplot[face];

			while (liste_plots != NULL) {

				plot = (loins_list * ) liste_plots->DATA;

				/* S'il s'agit d'un plot on regarde les signaux des connecteurs du plot pour
				trouver meme signal que con_coeur */

				/* if (mode_debug) printf("PLOT  %s de la face %d\n",plot->INSNAME,face);  */

				if ((con_plot = existe_sig_plot(sig_coeur, plot)) != NULL) {
					maj_equipo(con_coeur, con_plot, lst_equipo, COEUR_PLOT);
				}

				liste_plots = liste_plots->NEXT;
			} /* fin parcours instances plots d'une face */

		} /* fin  de parcours de toutes les faces */

		con_coeur = con_coeur->NEXT;

	} /* fin de parcours des con du coeur  */

	/*------------------------- equipo PLOT_PLOT -----------------------------------------*/

	for (i = 0; i < NB_FACES; i++) {
		liste_plots = nomplot[i];
		while (liste_plots != NULL) {

			plot = (loins_list * ) liste_plots->DATA;
			liste_con = plot->LOCON;

			while (liste_con != NULL) {
				pt_eq = existe_sig_equipo((*lst_equipo), (liste_con->SIG)->INDEX);
				signal_ok = ((pt_eq == NULL) || (pt_eq->type == PLOT_PLOT));

				if ((signal_ok) 
				&& (liste_con->NAME != n_vdde) 
				&& (liste_con->NAME != n_vsse) 
				&& (liste_con->NAME != n_vddi) 
				&& (liste_con->NAME != n_vssi) 
				&& (liste_con->NAME != n_pad)) {

					for (j = 0; j < NB_FACES; j++) {
						liste_plots2 = nomplot[j];

						while (liste_plots2 != NULL) {
							plot2 = (loins_list * ) liste_plots2->DATA;
							liste_con2 = plot2->LOCON;

							while (liste_con2 != NULL) {
								if ((liste_con2->NAME != n_vdde) 
								&&  (liste_con2->NAME != n_vsse) 
								&&  (liste_con2->NAME != n_vddi) 
								&&  (liste_con2->NAME != n_vssi) 
								&&  (liste_con2->NAME != n_pad)  
								&&  (liste_con2 != liste_con) 
								&& ((liste_con->SIG)->INDEX == (liste_con2->SIG)->INDEX)) {
								if (mode_debug) 
									printf("TROUVE liste_con ->%s *** %s\n", liste_con->NAME, liste_con2->NAME);
									maj_equipo(liste_con, liste_con2, lst_equipo, PLOT_PLOT);
								}
								liste_con2 = liste_con2->NEXT;
							}
							liste_plots2 = liste_plots2->NEXT;
						}
					}  /* ffin du for */
				} /* fin du if */
				liste_con = liste_con->NEXT;
			}
			liste_plots = liste_plots->NEXT; /* fin du  while */
		}

	}	 /* fin du 1er for */

	/*-------------------- equipo de type COEUR_COEUR  ----------------------------------*/

	tete_coeur = con_coeur = (lecoeur.coeur_lo)->LOCON;

	while (con_coeur != NULL) {
		pt_eq = existe_sig_equipo((*lst_equipo), (con_coeur->SIG)->INDEX);
		signal_ok = ((pt_eq == NULL) || (pt_eq->type == COEUR_COEUR));

		pt_coeur = tete_coeur;
		if (signal_ok)

			while (pt_coeur != NULL) {
				if ((pt_coeur != con_coeur) && ((con_coeur->SIG)->INDEX == (pt_coeur->SIG)->INDEX))
					maj_equipo(con_coeur, pt_coeur, lst_equipo, COEUR_COEUR);

				pt_coeur = pt_coeur->NEXT;
			}
		con_coeur = con_coeur->NEXT;
	}

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

	/* on  inverse les chain list de pseudo connecteurs associes a chaque equipo,
   ce qui a pour but de mettre le connecteur du coeur en tete de liste */

	liste = (*lst_equipo);

	while (liste != NULL) {
		liste->lst_con = reverse(liste->lst_con);
		liste = liste->suiv;
	}

}

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

/* Parcours des connecteurs de plots et des signaux associes */
/* Retourne le connecteur si signal identique                */

locon_list *existe_sig_plot(sig_coeur, plot)
losig_list *sig_coeur;
loins_list *plot;
{

	locon_list * con_plot = plot->LOCON;
	losig_list * sig_plot;

	/* if (mode_debug) printf("Existe sig_plot\n"); */

	/* Parcours des connecteurs du plot */

	while (con_plot != NULL) {
		/* if (mode_debug) printf("\tpointeur nom %d\n",(int)con_plot);  */
		sig_plot = con_plot->SIG; /* un signal unique par connecteur */

		/* if (mode_debug) printf("\tnom conplot %s signal %ld sigcoeur %ld\n",con_plot->NAME,sig_plot->INDEX,
	       sig_coeur->INDEX); */

		if (sig_plot->INDEX == sig_coeur->INDEX)
			return(con_plot);

		con_plot = con_plot->NEXT;
	}

	return(NULL);
}

