/****************************************************************************/
/*                                                                          */
/*                      Chaine de CAO & VLSI   Alliance                     */
/*                                                                          */
/*    Produit : ring router                                                 */
/*    Fichier : ring2.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 : 13/11/92       */
/*                                                                          */
/****************************************************************************/

#ident "@(#)ring 2.5 93/09/22 ALLIANCE pad ring router"
/*----------------------------------------------------------------------------------- */

/* RING    27 avril 92                      RING2.C */

/* Programme principal: declarations des variables (globales et locales) */

#include <stdio.h>
#include "includes.h"
#include "struct.h"

/*----------------------------------------------------------------------------------- */
/* Variables globales */
char	mode_debug;                      /* si debug alors mode_debug=1, 0 sinon */
char	mode_stat;                       /* si stat alors mode_stat=1, 0 sinon */
char	*nomfic_stat;                    /* nom du fichier stat */
char	xmetal;                          /* metal horizontal, faces est et Ouest */
char	ymetal;                          /* metal vertical, faces Nord et Sud */
long	xmetal_width, ymetal_width;      /* largeur des metaux x, y */
long	xmetal_dmin, ymetal_dmin;        /* dist minimum entre 2 meme metaux */
long	xmetal_wvia, ymetal_wvia;        /* taille des contacts pour chaque metal */
long	pitch;                           /* pitch a calculer */
long	lambda;                          /* lambda (=SCALE_X) */
long	taille_via;                      /* taille du via a calculer */
long	vdd_width;                       /* largeur couronnes d'alim */
long	vss_width;
char	*eq_vdd;                         /* nom equipo alim (fabrique_equipo()) */
char	*eq_vss;                         /* nom equipo alim */
char	*n_vdde;
char	*n_vsse;
char	*n_vddi;
char	*n_vssi;
char	*n_pad;

char	*nom_fic_param;                  /* nom du fichier parametre */

chain_list *nom_plot[NB_FACES];          /* liste pour l'analyseur des noms de plots */
                                         /* contiendra aussi les instances logiques de plots */
chain_list *liste_width;                 /* liste pour l'analyseur des noms
                                         et largeurs des connecteurs speciaux */

long	bigvias = 0, ringvias = 0;       /* nombres de vias poses en total par bigvia 
                                         ou en couronne (mode debug). car pb versatil
                                         si bcp de vias (fichier .cif enorme) */

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

main (argc, argv)
int	argc;
char	**argv;
{

	/* declarations des variables locales */

	BARRE_PLOTS    tab_plots[NB_FACES];      /* nbfaces barres de plots */
	LST_PSEUDO_CON tab_coeur[NB_FACES];      /* nbfaces listes de connecteurs du coeur */
	chain_list     * lst_width;              /* liste de pointeurs sur les connecteurs qui
	                                            ont des contraintes speciales (vdd, vss...) */

	chain_list     * liste_plotsph;          /* liste de pointeurs sur les modeles physiques
	                                            des plots */
	chain_list     * lst_conestouest;        /* liste des con estouest alim */

	int            nb_inst_plots;            /* nombres d'instances de plots rencontrees */

	GRILLE         tab_grilles[NB_FACES];    /* une grille symbolique par face */

	BARRE_PLOTS    tab_couts[NB_ITERATIONS]; /* tableau de stockage des couts du
                                                    placement de la barre des plots
	                                            en fonction de ses coordonnees */

	LST_EQUIPO     eq_externe;               /* liste des equipo. externes (connect. pads) */
	LST_EQUIPO     eq_width;                 /* liste des equipo. avec traitement special */
	LST_EQUIPO     eq_interne;               /* liste des equipo. internes (coeur/plots) */

	LST_SEGMENT    segx_occ[NB_FACES];       /* liste des segments occupes */
	LST_SEGMENT    segy_occ[NB_FACES];       /* liste des segments occupes */

	long	       piste_supalim[NB_FACES];  /* No des pistes alim couronnes inf et sup */

	long	       piste_infalim[NB_FACES];
	long	       tabpiste[NB_FACES];       /* No des 1eres pistes libres en partant 
                                                    de la barre de plots, sert pour les couronnes d'alim */

	char	       * nom_circuit_lo, *nom_circuit_ph; /* nom du circuit logique et resultat (physique) */

	COEUR          lecoeur;                  /* structure contenant les informations du coeur */

	lofig_list     * circuit_lo;             /* pointeur sur la figure logique du coeur */
	phfig_list     * circuit_ph;             /* pointeur sur la figure physique du coeur */

	char	       * coursup, *courinf;      /* nom des couronnes d'alim */
	long	       firstlibre[NB_FACES], nblibres[NB_FACES]; /* tab des 1eres pistes libres et nbre de piste */

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

	/* PHASE 1 */


	/* lecture et verification du nombre de parametres */
	lecture_param(argc, argv, &nom_circuit_lo, &nom_circuit_ph, &nom_fic_param);
	banner();

	/* PHASE 2 */
	/* lecture vues structurelles circuit et coeur */

	fprintf(stderr, "\to reading netlists, layout views of core and pads.\n");
	lecture_vues(nom_circuit_lo, &circuit_lo, &lecoeur, &liste_plotsph, &nb_inst_plots, &lst_conestouest);

	/* PHASE 3 */

	fprintf(stderr, "\to reading file of parameters, including the placements of pads.\n");
	lecture_fic(nom_fic_param, circuit_lo, lecoeur, nb_inst_plots);
	if (mode_debug) 
		affic_plotwidth();

	fprintf(stderr, "\to making equipotential list.\n");
	fabrique_equipo(nom_plot, lecoeur, &eq_interne);
	if (mode_debug) 
		affic_equipo(eq_interne);

	/* verification de la liste des equipotentielles internes */
	verif_eq_interne(eq_interne, liste_plotsph);

	/* PHASE 4 */

	fprintf(stderr, "\to making the first placement of pads.\n");
	fabrique_barre_plots(tab_plots, lecoeur, nom_plot, liste_plotsph, lst_conestouest);

	remplir_tabcoeur(tab_coeur, lecoeur, eq_interne);

	if (mode_debug) {
		printf("afficher tab_coeur\n"); 
		affic_tabcoeur(tab_coeur);
	}

	fprintf(stderr, "\to filling data internal structures.\n");
	remplir_tabplots(tab_plots, eq_interne);
	if (mode_debug) 
		affic_tabplots(tab_plots);

	if (mode_debug) 
		printf("*** (larg plot alim) vdd_width: %ld vss_width: %ld\n", vdd_width, vss_width);

	fprintf(stderr, "\to reading the connectors positions of the core.\n");
	fabrique_grille_primaire(tab_coeur, tab_grilles);
	if (mode_debug) 
		affic_grille(tab_grilles);

	fprintf(stderr, "\to computing the best placement of the pads.\n");
	place_et_cout_barreplot(tab_coeur, tab_plots, lecoeur, eq_interne);
	maj_coordplots(tab_plots, eq_interne);

	fprintf(stderr, "\to reading the connectors positions of the pads.\n");
	fabrique_grille_finale(tab_plots, tab_coeur, lecoeur, eq_interne, tab_grilles);
	if (mode_debug) 
		affic_grille(tab_grilles);
	if (mode_debug) 
		affic_tabplots(tab_plots);

	if (mode_debug) 
		affic_grille(tab_grilles);

	/* PHASE 5 */

	fprintf(stderr, "\to routing deportation of connectors.\n");
	attribuer_couronne_alim(eq_interne, &coursup, &courinf);

	/* initialisations de segx-occ[] et segy_occ[] */
	/* on alloue exceptionnellement des faux segments pour deport plot alim ! */
	deport_alim(eq_interne, tab_plots, coursup, courinf, segx_occ, segy_occ);

	deport_connecteurs(tab_plots, tab_coeur, lecoeur, tab_grilles);
	if (mode_debug) 
		affic_equipo(eq_interne);

	pose_segdeport(tab_plots, tab_coeur, lecoeur, eq_interne, segx_occ, segy_occ);

	fprintf(stderr, "\to routing supply tracks.\n");

	/* tabpiste va contenir les no des 1eres pistes libres en partant des plots
           qui vont servir pour poser les couronnes d'alim */

	pose_couralim(coursup, piste_supalim, piste_infalim, eq_interne, lecoeur, tab_plots, segx_occ, segy_occ, tabpiste);

	/* On peut se servir de tabpiste pour poser des faux segments, au cas ou on
           tire une alim ds le mauvais layer, ceci pour eviter des croisements 
           (courts-circuits) avec les deports eventuels de plots */

	tire_etdeport_alim(coursup, piste_supalim, piste_infalim, eq_interne, tab_plots, segx_occ, segy_occ, tabpiste);

	if (mode_debug) 
		printf("*** vdd_width: %ld vss_width: %ld\n", vdd_width, vss_width);
	if (mode_debug) 
		affic_equipo(eq_interne);

	/* PHASE 6 */

	fprintf(stderr, "\to routing equipotentials.\n");
	remplit_eq_curv(eq_interne, lecoeur);
	ordonne_equipotentielles(&eq_interne);

	route_equipo(piste_infalim, eq_interne, lecoeur, segx_occ, segy_occ);

	if (mode_debug) 
		affic_equipo(eq_interne);

	if (mode_debug) {
		printf("------------------------------------------------------------------\n\n\n");
		printf("SEGMENT YMETAL\n");
		affic_listeseg(segy_occ);
		printf("SEGMENT XMETAL\n");
		affic_listeseg(segx_occ);
	}

	/* PHASE 7 */

	fprintf(stderr, "\to compressing channels.\n");
	calcul_nbpiste_libre(tab_plots, lecoeur, segx_occ, segy_occ, nblibres, firstlibre);
	compression_canaux(tab_plots, lecoeur, segx_occ, segy_occ, nblibres, firstlibre);

	/* PHASE 8 */

	fprintf(stderr, "\to saving in MBK data structure.\n");
	poser_blocs(&circuit_ph, nom_circuit_ph, tab_plots, lecoeur);
	poser_segments(eq_interne, lecoeur, circuit_lo, circuit_ph);

	remonte_con_circuit(nom_plot, liste_plotsph, tab_plots, lecoeur, circuit_lo, circuit_ph, nom_circuit_ph, lst_conestouest);

	if (mode_stat) 
		finir_stat(eq_interne);

	fprintf(stderr, "lucky, no error.\n");
	exit(0); /* fin correcte du routeur */

}

