/********************************************************************
*                                                                   *
* Laboratoire MASI CAO-VLSI, UPMC, Copyright 1991 1992 1993 1994    *
*                                                                   *
* Software support Email : cao-vlsi@masi.ibp.fr                     *
*                                                                   *
* Authors : Zouina AKTOUF &                                         *
*           El Arabi RHOMARI &                                      *
*           Jose MARTINS DOS SANTOS                                 *
*                                                                   *
* Supervision & Modifications : Lotfi BEN AMMAR                     *
*                                                                   *
********************************************************************/
#include "dpr_R.h"
 
DPP_SPACE *tab[MAXLIN][MAXCOL];
long t[MAXLIN];
char *g[MAXLIN];
DPP_DATAPATH *ptdatapath;

/**************************************************************
**  dpp_strrch()
**************************************************************/
 long dpp_strrch(ptstr,car)
 char *ptstr;
 char car;
 {
 long i;

 for (i=strlen(ptstr);i>0;i--)
     if(ptstr[i]==car) return(i);
 return 0 ;
 }

/*************************************************************/
/*           Initialisation du tableau                        */
/**************************************************************/
void init()
{
int i, j;
for(i=0; i<MAXLIN; i++)
    {
    for(j=0; j<MAXCOL; j++)
       {
       tab[i][j]=0;
       }
    }
}
/**************************************************************/
/* Recherche d'un underscore dans le nom d'une instance       */
/*    et test de l'index du bit slice                         */
/**************************************************************/
int test_insname(name)
char *name;
{
char *s;
int str, p;
int i=0;
int index=0;
s=strrchr(name,'_');
if (s==NULL)
   {
   str=-1;
   }
else
   {
    while (s[i] !='\0'){
           p=isdigit(s[++i]);
           if (p==0) index=index+1;
           if (index > 1){
                      fprintf(stdout,"The instance index is not an integer!\n");
                      exit(1);
                           }
                        }
     
     str=atoi(s+1);
    }
return(str);
}
/*****************************************************************/
/*Comparer un nom de connecteur fixe avec un nom de connecteur DF*/
/*****************************************************************/
int test_connector_name(con_name, df_name)
char *con_name;
char *df_name;
{
char *con_test=NULL;
char *df_test=NULL;
char *s=NULL;
char *croch1=NULL;
char *croch2=NULL;
char *esp=NULL;
char *esp1=NULL;
int i=0;
int con=0;
int df=0;
int flag=0;

con_test=malloc(sizeof(con_name));
df_test=malloc(sizeof(df_name));

strcpy(con_test, con_name);
strcpy(df_test, df_name);

s=strchr(df_test,'[');
if(s !=NULL)
  {
  croch1=strchr(df_test,'[') ;
  croch2=strchr(df_test,']') ;
  croch1[0]='\0';
  croch2[0]='\0';
  strcat(df_test,s+1);
  }
esp=strchr(con_test,' ');
if(esp !=NULL)
  {
  esp1=strchr(con_test,' ');
  esp1[0]='\0';
  strcat(con_test,esp+1);
  }
if(strcmp(con_test,df_test)!=0)
  {
  flag=1;
  }
return(flag);
}
/**************************************************************/
/*         Test de la valeur de la  variable d'environnement  */
/*         MBK_SEPAR                                          */      
/**************************************************************/
char get_MBK_SEPAR()
{
char *s=NULL;
s=getenv("MBK_SEPAR");
if(s==NULL) return('.');
else return(s[0]);
}
/**************************************************************/
/*      Extraction de la chaine de caracteres se trouvant     */
/*      avant le point(apres la mise a plat de la netlist)    */      
/**************************************************************/
char *extract(s,c)
char *s;
char c;
{
char *p=NULL;
char *name=NULL;
int n=0;

p = strchr(s,c);
if (p!=NULL)
   {
   n = p - s;
   name = malloc(n+1);
   strncpy(name,s,n);
   name[n]='\0';
  }  
return(name);
}

/******************************************************************************/
/* Ajoute un element en debut de la liste pointe par LeadIndexList            */
/******************************************************************************/
DPP_GET_INDEX_LIST  *AddIndexList(LeadIndexList,InsName,UpFig,UpIns,Index)
DPP_GET_INDEX_LIST  *LeadIndexList;
char		*InsName;
char		*UpFig;
char		*UpIns;
int		 Index;

{
 DPP_GET_INDEX_LIST  *ptIndex;

 ptIndex = ((DPP_GET_INDEX_LIST *)mbkalloc(sizeof(DPP_GET_INDEX_LIST)));
 ptIndex->NEXT = LeadIndexList;
 ptIndex->INSNAME = InsName;
 ptIndex->UPFIG = UpFig;
 ptIndex->UPINS = UpIns;
 ptIndex->INDEX = Index;

 return(ptIndex);
}

/**************************************************************/
/*      Test des niveaux hierarchiques                        */
/**************************************************************/
DPP_GET_INDEX_LIST *hierarchy(ptlo)
lofig_list *ptlo;
{
int j=1, p=0;
lofig_list *ptfigins1=NULL;
loins_list *ptloins1=NULL, *ptloins2=NULL;
DPP_GET_INDEX_LIST *LeadIndexList=NULL;
int nbcol=1;

for(ptloins1=ptlo->LOINS;ptloins1;nbcol++,ptloins1=ptloins1->NEXT);

for(ptloins1=ptlo->LOINS;ptloins1;ptloins1=ptloins1->NEXT)
   {
   if (incatalog(ptloins1->FIGNAME)!=0)
      {
      printf("First Hierarchical Level: %s in CATAL\n",ptloins1->FIGNAME);
      LeadIndexList = AddIndexList(LeadIndexList,ptloins1->INSNAME, 
                                   ptlo->NAME,ptlo->NAME,nbcol-j);
      }
   else
      {
      ptfigins1 = getlofig(ptloins1->FIGNAME,'A');
      if (ptfigins1->LOINS==NULL) /* pas d'instances au 2eme niveau */
         {
         printf("Error: %s is not in the CATAL, must be a second hierarchical level!\n",
                 ptloins1->FIGNAME);
         exit(1);
         }
      else  /*presence de fils au 2eme niveau hierarchique */
         { 
         for (ptloins2=ptfigins1->LOINS;ptloins2;ptloins2=ptloins2->NEXT)
             {
             p = incatalog(ptloins2->FIGNAME);
             if (p==0)
                {
                printf("Error: %s is not in the CATAL!\n",ptloins2->FIGNAME);
                exit(2);
                }
             else /* 2eme niveau OK */
                {
                LeadIndexList = AddIndexList(LeadIndexList,ptloins2->INSNAME, 
                                             ptloins1->FIGNAME,ptloins1->INSNAME,nbcol-j);
                }
             }
         }
      }
   j++;
   }
return(LeadIndexList);
}
/****************************************************************/
/*    Nombre de cases du tableau que peut occuper une cellule   */
/*    ou un bloc.                                               */
/****************************************************************/
int  nb_cases(pt)
phfig_list *pt;
{
char *vdd, *vss;
int nb_vdd=0, nb_vss=0, nb=0;
int nb_vdd_egaux=0, nb_vss_egaux=0; 
phcon_list *ptcon1, *ptcon2;

vdd = namealloc("vdd");
vss = namealloc("vss");
for (ptcon1=pt->PHCON;ptcon1;ptcon1=ptcon1->NEXT)
    {
    if ((ptcon1->LAYER==(char)ALU2) &&
        (strncmp(vdd,ptcon1->NAME,3)==0))
       {
       nb_vdd_egaux = 0;
       for (ptcon2=pt->PHCON;ptcon2!=ptcon1;ptcon2=ptcon2->NEXT)
           {
           if ((ptcon2->LAYER==(char)ALU2) &&
               (strncmp(vdd,ptcon2->NAME,3)==0))
              {
              if (ptcon2->YCON==ptcon1->YCON)
                 {
                 nb_vdd_egaux++;
                 }
              }
           }
       if (nb_vdd_egaux==0)
          nb_vdd++;
       }
    else 
       if ((ptcon1->LAYER==(char)ALU2) && 
           (strncmp(vss,ptcon1->NAME,3)==0))
          {
          nb_vss_egaux = 0;
          for (ptcon2=pt->PHCON;ptcon2!=ptcon1;ptcon2=ptcon2->NEXT)
              {
              if ((ptcon2->LAYER==(char)ALU2) &&
                  (strncmp(vss,ptcon2->NAME,3)==0))
                 {
                 if (ptcon2->YCON==ptcon1->YCON)
                    {
                    nb_vss_egaux++;
                    }
                 }
              }
          if (nb_vss_egaux==0)
             nb_vss++;
          }
    nb = nb_vdd + nb_vss - 1;
    }
return(nb);
}
/****************************************************************/
/*    Nombre de lignes et de colonnes du tableau                */
/****************************************************************/
void table(pt,lig,col)
lofig_list *pt;
int *lig;
int *col;
{
loins_list *ptins1=NULL;
loins_list *ptins2=NULL;
lofig_list *ptfigins1=NULL;
phfig_list *phfig1=NULL;
phfig_list *phfig2=NULL;
int max1=0;
int max2=0;
int max=0;
int maxi=0;

for (ptins1=pt->LOINS;ptins1;ptins1=ptins1->NEXT)
    {
    (*col)++;
    if (incatalog(ptins1->FIGNAME)==0)
       {
       ptfigins1 = getlofig(ptins1->FIGNAME,'A');
       max2 = 0;
       for (ptins2=ptfigins1->LOINS;ptins2;ptins2=ptins2->NEXT)
           {
           phfig2 = getphfig(ptins2->FIGNAME,'P');
           max2 = (max2 + nb_cases(phfig2));
           }
       if (max2>maxi)
          maxi = max2;
       }
    else
       {
       phfig1 = getphfig(ptins1->FIGNAME,'P');
       max1 = nb_cases(phfig1);
       if (max1>max)
          max = max1;
       }
    }
if (max>maxi)
   (*lig) = max;
else
   (*lig) = maxi;
}
/****************************************************************/
/*      Calcul de l'ordonnee de la premiere barre d'alim       */
/****************************************************************/
int ord_alim(pt)
phfig_list *pt;
{
phcon_list *ptcon=NULL;
int y=0;
int ymin=0;
int first=0;
char *vss;
char *vdd;

vss=namealloc("vss");     
vdd=namealloc("vdd");     
for(ptcon=pt->PHCON;ptcon;ptcon=ptcon->NEXT)
   {
    if (ptcon->LAYER==(char)ALU2)
       {
        if(strncmp(vss,ptcon->NAME,3)==0 || strncmp(vdd,ptcon->NAME,3)==0)
          y=ptcon->YCON;
        if(first==0)
          {
           ymin=y;
           first=1;
          }
        else if(y<ymin) ymin=y; 
       }
   }
return(ymin);
}
/****************************************************************/
/*      Calcul de la hauteur d'un bit_slice                     */
/****************************************************************/
int height(pt)
phfig_list *pt;
{
phcon_list *ptcon;
char *vdd, *vss;
long y1, y2, diff;

vdd=namealloc("vdd");
vss=namealloc("vss");     
for(ptcon=pt->PHCON;ptcon;ptcon=ptcon->NEXT)
   {
    if (ptcon->LAYER==(char)ALU2)
       {
        if(strncmp(vdd,ptcon->NAME,3)==0)
          y1=ptcon->YCON;
        else if(strncmp(vss,ptcon->NAME,3)==0)
          y2=ptcon->YCON;
       }
       diff=abs(y2 - y1);
   }
return(diff);
}
/****************************************************************/
/*      Calcul de la largeur d'une case du tableau              */
/****************************************************************/
long width(pt)
phfig_list *pt;
{
return((pt->XAB2) - (pt->XAB1));
}
/****************************************************************/
/*              test de l'aboutabilite                          */
/****************************************************************/
void test_abut(c,ptspace,CON,ptins,phfig)
char c;
DPP_SPACE *ptspace;
chain_list *CON;
loins_list *ptins;
phfig_list *phfig;
{
DPP_CONNECTOR *con_s=NULL;
phcon_list *ptcon=NULL, *p=NULL;
locon_list *ptlocon=NULL;
chain_list *connector=NULL;
chain_list *s=NULL;
DPP_POSSIBILITY *pos=NULL;
int up, okk, ok;
int ind=0;/*indicateur de l'equipotentialite de 2 connecteurs*/
char *vss, *vdd;

vdd=namealloc("vdd");
vss=namealloc("vss");

for(ptcon=phfig->PHCON;ptcon;ptcon=ptcon->NEXT)
   {
   if ((strncmp(vdd,ptcon->NAME,3)!=0)&&(strncmp(vss,ptcon->NAME,3)!=0))
      {
      if (ptcon->ORIENT==c)
         {
         for(connector=CON;connector;connector=connector->NEXT)
            {
            con_s = (DPP_CONNECTOR *)connector->DATA;
            for(s=con_s->POS;s;s=s->NEXT)
               {
               pos = (DPP_POSSIBILITY *)s->DATA;
               if (pos->XCON==(ptcon->XCON-phfig->XAB1))
                  {
                  /*verifier l'equipotentialite entre les 2 connecteurs*/
                  /*ayant le meme abscisse*/
                  for(ptlocon=ptins->LOCON;ptlocon;ptlocon=ptlocon->NEXT)
                     {
                     if (strcmp(ptlocon->NAME,ptcon->NAME)==0)
                        {
                        break;
                        }
                     }
                  if (ptlocon)
                     {
                     if (con_s->SIGN->index==ptlocon->SIG->INDEX)
                        {
                        con_s->USER = addchain(con_s->USER,(void *)ok);
                        }
                     else
                        {
        printf("WARNING: Abutability problem for signal %s between %s and %s!\n",
                        getsigname(ptlocon->SIG),ptins->INSNAME,ptspace->INSNAME);
                        }
                     }
                  else
                     {
        printf("Error: Physical terminal %s with no logical corresponding in %s!\n",
                     ptcon->NAME,phfig->NAME);
                     exit(10);
                     }
                  }
               }
            }
         }
      }
   }
for(connector=CON;connector;connector=connector->NEXT)
   {
   con_s = (DPP_CONNECTOR *)connector->DATA;
   if (con_s->USER==NULL)
      {
      printf("WARNING: Abutability problem for signal %s between %s and %s!\n",
                       con_s->SIGN->NAME,ptins->INSNAME,ptspace->INSNAME);
      }
   }
}
/********************************************************************/
/*     Aboutabilite sud: Recherche d'un connecteur ayant            */ 
/*                       la meme abscisse.                          */  
/********************************************************************/
void abut_S(car,ptins,phfig, i, j, l)
char car;
loins_list *ptins;
phfig_list *phfig;
int i, j;
int l;
{
DPP_SPACE *ptspdown=NULL ; 
phcon_list *ptcon=NULL;
char *vdd, *vss;
int mask=1;
int down;
int command=0;

vdd=namealloc("vdd");
vss=namealloc("vss");     
down = (i-1);
if(down>=0)
  {
   ptspdown=tab[down][j];
   if(ptspdown!=NULL)
     {
     /*presence ou pas de commandes verticales*/
     for(ptcon=phfig->PHCON;ptcon;ptcon=ptcon->NEXT)
        {
        if(strncmp(vdd,ptcon->NAME,3)!=0 && strncmp(vss,ptcon->NAME,3)!=0) 
          {
          if (((ptcon->ORIENT=='S')&&(car=='P'))||
              ((ptcon->ORIENT=='N')&&(car=='I')))
             {
             command=1;
             break;
             } 
          }
        }
     if (ptspdown->N_CON!=NULL)
        {
        if (command==1)
           {  
           if (car=='P')
              {
              test_abut('S',ptspdown,ptspdown->N_CON,ptins,phfig);
              }
           else /* car=='I' */
              {
              test_abut('N',ptspdown,ptspdown->N_CON,ptins,phfig);
              }
           }  
        else /* command==0 */
           {
           printf("Warning: Abutabily problems may exist between %s and %s\n",
                   ptins->INSNAME,ptspdown->INSNAME);
           }
        }
     else /* ptspdown->N_CON==NULL */
        {  
        if (command==1)
           {
           printf("Warning: Abutabily problems may exist between %s and %s\n",
                   ptins->INSNAME,ptspdown->INSNAME);
           }
        }
     }
  }
}
/********************************************************************/
/*     Aboutabilite nord: Recherche d'un connecteur ayant           */ 
/*                             la meme abscisse.                    */  
/********************************************************************/
void abut_N(car, ptins,phfig, nb, i, j, l)
char car;
loins_list *ptins;
phfig_list *phfig;
int nb;
int i, j;
int l;
{
DPP_SPACE *ptspup=NULL ; 
phcon_list *ptcon=NULL;
char *vdd, *vss;
int mask=1;
int up;
int command=0;

vdd=namealloc("vdd");
vss=namealloc("vss");     

up=(i + nb);
if(up<l)
  {
   ptspup=tab[up][j];
   if(ptspup!=NULL)
     {
     /*presence ou pas de commandes verticales*/
     for(ptcon=phfig->PHCON;ptcon;ptcon=ptcon->NEXT)
        {
        if(strncmp(vdd,ptcon->NAME,3)!=0&&strncmp(vss,ptcon->NAME,3)!=0) 
          {
          if (((ptcon->ORIENT=='N')&&(car=='P'))||
              ((ptcon->ORIENT=='S')&&(car=='I')))
             {
             command=1;
             break;
             }
          }
        }
     if (ptspup->S_CON!=NULL)
        {
        if (command==1)
           {
           if (car=='P')
              {
              test_abut('N',ptspup,ptspup->S_CON,ptins,phfig);        
              }
           else /* car=='I' */
              {
              test_abut('S',ptspup,ptspup->S_CON,ptins,phfig);        
              }
           }
        else /* command==0 */
           {
           printf("Warning: Abutabily problems may exist between %s and %s\n",
                   ptins->INSNAME,ptspup->INSNAME);
           }
        }
     else /* ptspup->S_CON==NULL */
        {
        if (command==1)
           {
           printf("Warning: Abutabily problems may exist between %s and %s\n",
                   ptins->INSNAME,ptspup->INSNAME);
           }
        }
     }
  }
}
/******************************************************************/
/*          Calcul du minimum dans une liste d'index              */ 
/******************************************************************/
int min(j, i)
int j, i;
{
int minimum=0;

if(j < i) minimum=j;
else if(i < j)minimum=i;

return(minimum);
}
/********************************************************************/
/*      Makespace:Remplissage de la structure DPP_SPACE                 */
/********************************************************************/
DPP_SPACE *makespace(insname, figname, upfig, upins, width, nbcase, i, j)
char *insname;
char *figname;
char *upfig;
char *upins;
int  width, nbcase;
int i, j;
{
chain_list *p=NULL;
chain_list *s=NULL;
DPP_SIGNAL *sig;
chain_list *signal;
DPP_SPACE *ptspace;
DPP_CONNECTOR *ptname;
ptspace=(DPP_SPACE *)mbkalloc(sizeof(struct ADPP_SPACE));
ptspace->INSNAME=insname;
/*printf("***************************************************************\n");*/
/*printf("insname:%s\n",ptspace->INSNAME);*/
ptspace->FIGNAME=figname;
/*printf("figname:%s\n",ptspace->FIGNAME);*/
ptspace->UPFIG=upfig;
/*printf("upfig(makespace):%s\n",ptspace->UPFIG);*/
ptspace->UPINS=upins;
/*printf("upins(makespace):%s\n",ptspace->UPINS);*/
ptspace->WIDTH=width;
/*printf("width:%d\n",ptspace->WIDTH);*/
ptspace->HEIGHT=0;
/*printf("height:%d\n",ptspace->HEIGHT);*/
ptspace->NBCASE=nbcase;
/*printf("nbcase:%d\n",ptspace->NBCASE);*/
ptspace->I=i;
/*printf("LIGNE=%d\n",ptspace->I);*/
ptspace->J=j;
/*printf("COLONNE=%d\n",ptspace->J);*/
ptspace->X=0;
ptspace->Y=0;
ptspace->N_CON=NULL;
ptspace->S_CON=NULL;
ptspace->DF_CON=NULL;
ptspace->SIG=NULL;
ptspace->SEG=NULL;
ptspace->TRACK_CAPACITY=0;
/*printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");*/
return(ptspace);
}
/****************************************************************/
/*       makecon:Remplissage de la structure DPP_CONNECTOR    */
/****************************************************************/
DPP_CONNECTOR *makecon(pt,c,ptspace, i, j)
phcon_list *pt;
char c;
DPP_SPACE *ptspace;
int i, j;
{
DPP_CONNECTOR *ptcon;
ptcon=(DPP_CONNECTOR *)mbkalloc(sizeof(struct ADPP_CONNECTOR));
ptcon->NAME=pt->NAME;
ptcon->LIN=i;
ptcon->COL=j;
ptcon->ORIENT=c;
ptcon->INS=ptspace;
ptcon->POS=NULL;
ptcon->SIGN=NULL;
ptcon->USER=NULL;

return(ptcon);
}
/****************************************************************/
/*       makecon_df:Remplissage de la structure DPP_CONNECTOR       */
/*                  pour les connecteurs DF                     */
/****************************************************************/
DPP_CONNECTOR *makecon_df(name,ptspace, i, j)
char *name;
DPP_SPACE *ptspace;
int i, j;
{
DPP_CONNECTOR *ptcref;

ptcref=(DPP_CONNECTOR *)mbkalloc(sizeof(struct ADPP_CONNECTOR));
ptcref->NAME=(char *)mbkalloc(20);
strcpy(ptcref->NAME,name);
ptcref->LIN=i;
ptcref->COL=j;
ptcref->ORIENT='X';
ptcref->INS=ptspace;
ptcref->POS=NULL;
ptcref->SIGN=NULL;
ptcref->USER=NULL;

return(ptcref);
}
/****************************************************************/
/*       Fonction dpp_insertsig:Creation de la structure DPP_SIGNAL     */
/****************************************************************/
void dpp_insertsig(ptspace,ptphcon, sig_mbk, i, j)
DPP_SPACE      *ptspace;
DPP_CONNECTOR  *ptphcon;
losig_list *sig_mbk;
int i, j;
{
int max=0;
chain_list *ptcsig=NULL;
chain_list *ptcsig_ins=NULL;
DPP_SIGNAL *ptsig=NULL;
DPP_SIGNAL *ptsig_ins=NULL;

/* verifier si le signal existe dans la liste des signaux de DPP_DATAPATH */
for(ptcsig=ptdatapath->SIG;ptcsig;ptcsig=ptcsig->NEXT)
   {
   ptsig = (DPP_SIGNAL *)ptcsig->DATA;
   if (ptsig->index==sig_mbk->INDEX)
      break;
   }  
if(ptcsig==NULL) /* Creation d'un nouveau signal */
   {
   ptsig=(DPP_SIGNAL *)mbkalloc(sizeof(struct ADPP_SIGNAL));
   ptsig->NAME=getsigname(sig_mbk);
   ptsig->index=sig_mbk->INDEX;
   ptsig->type=sig_mbk->TYPE;
   ptsig->MIN_COL=j;
   ptsig->TMP_MIN_COL=j;
   ptsig->width=0;
   ptsig->TMP_width=0;
   ptsig->COMPUTE=1;
   ptsig->MIN_LIN=i;
   ptsig->height=0;
   ptsig->COL=addchain((chain_list *)NULL, (void *)j);
   ptsig->LIN=addchain((chain_list *)NULL, (void *)i);
   ptsig->CON=addchain((chain_list *)NULL, (void *)ptphcon);
   ptsig->USER=NULL;

   /*Rajouter le signal a la liste des signaux de la figure*/
   ptdatapath->SIG=addchain(ptdatapath->SIG,(void *)ptsig);

   /*Rajouter le signal a la liste des signaux de l'instance*/
   ptspace->SIG=addchain(ptspace->SIG,(void *)ptsig);
 
   /*Rattacher le connecteur a son signal */
   ptphcon->SIGN=ptsig;
   }
else /* Si le signal existe deja */
   {
   for(ptcsig_ins=ptspace->SIG;ptcsig_ins;ptcsig_ins=ptcsig_ins->NEXT)
      {
      ptsig_ins=(DPP_SIGNAL *)ptcsig_ins->DATA;
      if(ptsig_ins->index==sig_mbk->INDEX)
      break;
      }  
   /*Verifier si l'instance figure dans la liste des instances du signal */
   if(ptcsig_ins==NULL) /* Creation d'un nouveau signal pour l'instance */
     {
     /*Rajouter le signal a la liste des signaux de l'instance*/
     ptspace->SIG=addchain(ptspace->SIG,(void *)ptsig);
     }
   ptsig=(DPP_SIGNAL *)ptcsig->DATA;

   /* Reactualiser MIN_COL, MIN_LIN, la largeur  et la hauteur d'un signal
   ainsi que les champs COL et LIN de la structure DPP_SIGNAL              */

   ptsig->COL=addchain(ptsig->COL, (void *)j);
   ptsig->LIN=addchain(ptsig->LIN, (void *)i);
   ptsig->height=i-(ptsig->MIN_LIN);
   if(j < ptsig->MIN_COL)
     {
     ptsig->width=((ptsig->MIN_COL + ptsig->width)-j);
     ptsig->MIN_COL=j;
     ptsig->TMP_MIN_COL=ptsig->MIN_COL;
     ptsig->TMP_width=ptsig->width;
     }
   else if(j > (ptsig->MIN_COL + ptsig->width))
     {
     ptsig->width=(j - ptsig->MIN_COL);
     ptsig->TMP_width=ptsig->width;
     }
   ptsig->CON=addchain(ptsig->CON,(void *)ptphcon);

   /*Rattacher le connecteur a son signal */
   ptphcon->SIGN=ptsig;
  }
}
/****************************************************************/
/*       pos();possibilite pour un connecteur                   */
/****************************************************************/
DPP_POSSIBILITY *pos(phfig, ptcon)
phfig_list *phfig;
phcon_list *ptcon;
{
DPP_POSSIBILITY *ptpos=NULL;
ptpos=(DPP_POSSIBILITY *)mbkalloc(sizeof(struct ADPP_POSSIBILITY));
ptpos->XCON=(ptcon->XCON - phfig->XAB1);
ptpos->YCON=ptcon->YCON;
ptpos->LAYER=ptcon->LAYER;
return(ptpos);	
}
/****************************************************************/
/*       pos_ref():possibilites pour un connecteur virtuel      */
/****************************************************************/
DPP_POSSIBILITY *pos_ref(phfig, ptref)
phfig_list *phfig;
phref_list *ptref;
{
DPP_POSSIBILITY *ptpos=NULL;
ptpos=(DPP_POSSIBILITY *)mbkalloc(sizeof(struct ADPP_POSSIBILITY));
ptpos->XCON=(ptref->XREF - phfig->XAB1);
ptpos->YCON=ptref->YREF;
ptpos->LAYER=10;
return(ptpos);	
}
/****************************************************************/
/*         nord():Remplir le champ N_CON de la structure DPP_SPACE   */
/****************************************************************/
void nord(phfig,ptcon,ptspace,ptsig,i,j)
phfig_list *phfig;
phcon_list *ptcon;
DPP_SPACE *ptspace;
losig_list *ptsig;
int i,j;
{
int found=1;
chain_list *con_n=NULL;
DPP_CONNECTOR *phccon=NULL;
DPP_POSSIBILITY  *pos_con=NULL;

for(con_n=ptspace->N_CON;con_n;con_n=con_n->NEXT)
   {                                           
   phccon=(DPP_CONNECTOR *)con_n->DATA;
   found=strcmp(phccon->NAME,ptcon->NAME);
   if(found==0) break;
   }                                           
  if(found!=0)
    {
     phccon=makecon(ptcon,'N',ptspace, i, j);
     ptspace->N_CON=addchain(ptspace->N_CON,(void *)phccon);
     dpp_insertsig(ptspace,phccon, ptsig,i,j);
     pos_con=pos(phfig, ptcon);
     phccon->POS=addchain((chain_list *)NULL,(void *)pos_con);
     }
  else
     { 
     pos_con=pos(phfig, ptcon);
     phccon->POS=addchain(phccon->POS,(void *)pos_con);
     }
}
/****************************************************************/
/*         sud():Remplir le champ S_CON de la structure DPP_SPACE   */
/****************************************************************/
void sud(phfig, ptcon,ptspace,ptsig,i,j)
phfig_list *phfig;
phcon_list *ptcon;
DPP_SPACE *ptspace;
losig_list *ptsig;
int i,j;
{
int found=1;
chain_list *con_s=NULL;
DPP_CONNECTOR *phccon=NULL;
DPP_POSSIBILITY  *pos_con=NULL;

for(con_s=ptspace->S_CON;con_s;con_s=con_s->NEXT)
   {                                           
    phccon=(DPP_CONNECTOR *)con_s->DATA;
    found=strcmp(phccon->NAME,ptcon->NAME);
    if(found==0) break;
   }                                           
if(found!=0)
   {
    phccon=makecon(ptcon,'S',ptspace, i, j);
    ptspace->S_CON=addchain(ptspace->S_CON,(void *)phccon);
    dpp_insertsig(ptspace,phccon, ptsig,i,j);
    pos_con=pos(phfig, ptcon);
    phccon->POS=addchain((chain_list *)NULL,(void *)pos_con);
    }
else
   { 
    pos_con=pos(phfig, ptcon);
    phccon->POS=addchain(phccon->POS,(void *)pos_con);
    }
}
/****************************************************************/
/*      data_f():Remplir le champ DF_CON de la structure DPP_SPACE   */
/****************************************************************/
void data_f(phfig, ptcon,ptspace,ptsig,i,j)
phfig_list *phfig;
phcon_list *ptcon;
DPP_SPACE *ptspace;
losig_list *ptsig;
int i,j;
{
int found=1;
chain_list *con_df=NULL;
DPP_CONNECTOR *phccon=NULL;
DPP_CONNECTOR *phcref=NULL;
DPP_POSSIBILITY  *pos_con=NULL;
DPP_POSSIBILITY  *poss_ref=NULL;

for(con_df=ptspace->DF_CON;con_df;con_df=con_df->NEXT)
   {                                           
    phccon=(DPP_CONNECTOR *)con_df->DATA;
    found=strcmp(phccon->NAME,ptcon->NAME);
    if(found==0) break;
    }                                           
if(found!=0)
   {
    phccon=makecon_df(ptcon->NAME,ptspace, i, j);
    ptspace->DF_CON=addchain(ptspace->DF_CON,(void *)phccon);
    dpp_insertsig(ptspace,phccon, ptsig,i,j);
    pos_con=pos(phfig, ptcon);
    phccon->POS=addchain((chain_list *)NULL,(void *)pos_con);
    }
    else
   { 
    pos_con=pos(phfig, ptcon);
    phccon->POS=addchain(phccon->POS,(void *)pos_con);
    }
}
/****************************************************************/
/*       cree_con:Creer la structure DPP_CONNECTOR a partir de      */
/*                la structure phcon_list et phref_list         */
/****************************************************************/
void cree_con(index,k, ymin, ymax,compt,pt,ptspace,phfig, ptlocon,ptsig,i,j)
int index;
int k;
long ymin;
long ymax;
int compt;
lofig_list *pt;
DPP_SPACE  *ptspace;
phfig_list *phfig;
locon_list *ptlocon;
losig_list *ptsig;
int i,j;

{
int mask=1;
phcon_list *ptcon=NULL;
phref_list *ptref=NULL;
DPP_CONNECTOR *phcref=NULL;
DPP_POSSIBILITY  *poss_ref=NULL;
char *underscore;
char *vdd, *vss, *nwell, *ref_con;
int found;
char *name=NULL;
chain_list *df=NULL;
chain_list *con_n=NULL;
chain_list *con_s=NULL;
chain_list *con_df=NULL;
DPP_CONNECTOR *con=NULL;
long placed=1;
long icour,imax;
char ptauxname[20];

vdd=namealloc("vdd");
vss=namealloc("vss");     
nwell=namealloc("nwell");
ref_con=namealloc("ref_con");

for(ptcon=phfig->PHCON;ptcon;ptcon=ptcon->NEXT)
  {
  if((strncmp(vdd,ptcon->NAME,3)!=0) &&( strncmp(vss,ptcon->NAME,3)!=0) 
                                     &&(strncmp(nwell,ptcon->NAME,4)!=0)
                                     &&(strcmp(ptlocon->NAME,ptcon->NAME)==0))
    {                                           
    if((ptcon->YCON >= ymin) && (ptcon->YCON <= ymax)) 
      {
     if(strcmp(ptspace->UPFIG,pt->NAME)==0 || (mask & i)==0)/*index pair:nosym*/
       {
         ptcon->USER=addptype(ptcon->USER,(long)placed,(void *)placed);
         if(ptcon->ORIENT=='N')
          {
          nord(phfig,ptcon,ptspace,ptsig,i+k,j);
          }
         else if(ptcon->ORIENT=='S')
          {
          sud(phfig,ptcon,ptspace,ptsig,i+k,j);
          }
         else
          {
          data_f(phfig,ptcon,ptspace,ptsig,i+k,j);
          }
        }
     else if(strcmp(ptspace->UPFIG,pt->NAME)!=0 && (mask & i)==1) 
        {
         if(ptcon->ORIENT=='N')
          {
          sud(phfig,ptcon,ptspace,ptsig,i+compt,j);
          }
         else if(ptcon->ORIENT=='S')
          {
          nord(phfig,ptcon,ptspace,ptsig,i+compt,j);
          }
         else
          {
          data_f(phfig,ptcon,ptspace,ptsig,i+compt,j);
          }
        }
      }
     }
   }
for(ptref=phfig->PHREF;ptref;ptref=ptref->NEXT)
   {
    if(ptref->FIGNAME == ref_con)
     {                                           
    if((ptref->YREF >= ymin) && (ptref->YREF <= ymax)) 
      {
      imax = dpp_strrch(ptref->NAME,'_');
      if (imax==0)
         {
         printf("DPP Error: Virtual terminal %s in %s not valid\n",
                 ptref->NAME,phfig->NAME);
         exit(11);
         }
      for (icour=0;icour<imax;icour++)
          ptauxname[icour] = ptref->NAME[icour];
      ptauxname[imax]='\0';                                           
      name = namealloc(ptauxname);
     if(ptlocon->NAME==name)
       {
       found=1;
       for(df=ptspace->DF_CON;df;df=df->NEXT)
          {
          phcref=(DPP_CONNECTOR *)df->DATA;
          found=strcmp(phcref->NAME,name);
          if(found==0) break;
          }
       if(found!=0)
         {
         phcref=makecon_df(name,ptspace, i+k, j);
         ptspace->DF_CON=addchain(ptspace->DF_CON,(void *)phcref);
         dpp_insertsig(ptspace,phcref, ptsig,i+k,j);
         poss_ref=pos_ref(phfig, ptref);
         phcref->POS=addchain(phcref->POS,(void *)poss_ref);
         }
       else
        {
        poss_ref=pos_ref(phfig, ptref);
        phcref->POS=addchain(phcref->POS,(void *)poss_ref);
        }
      }
    }
   }                                           
 }
}
/****************************************************************/
/*       seg:Liste des segments horizontaux en TALU2            */   
/****************************************************************/
void seg(k,haut,phfig, ptspace)
int k;
int haut;
phfig_list  *phfig;
DPP_SPACE  *ptspace;
{
int flag=1;
chain_list *s=NULL;
DPP_SEGMENT *sceg=NULL;
phseg_list *pseg=NULL;
DPP_SEGMENT *ptseg=NULL;
for(pseg=phfig->PHSEG;pseg;pseg=pseg->NEXT)
   {
   if ((pseg->TYPE=='R' || pseg->TYPE=='L') &&
       (pseg->LAYER==TALU2) &&
       ((pseg->Y1>=(k*haut)+phfig->YAB1)&&(pseg->Y1<=((k+1)*haut)+phfig->YAB1)))
      {
      if (flag==1)
         {  
         ptseg=(DPP_SEGMENT *)mbkalloc(sizeof(struct ADPP_SEGMENT));
         ptseg->NAME=pseg->NAME;
         ptseg->X1=pseg->X1;
         ptseg->Y1=pseg->Y1;
         ptseg->X2=pseg->X2;
         ptseg->Y2=pseg->Y2;
         ptseg->WIDTH=pseg->WIDTH;
         ptspace->SEG=addchain((chain_list *)NULL, (void *)ptseg);
         flag=0;
         }  
      else
         {  
         ptseg=(DPP_SEGMENT *)mbkalloc(sizeof(struct ADPP_SEGMENT));
         ptseg->NAME=pseg->NAME;
         ptseg->X1=pseg->X1;
         ptseg->Y1=pseg->Y1;
         ptseg->X2=pseg->X2;
         ptseg->Y2=pseg->Y2;
         ptseg->WIDTH=pseg->WIDTH;
         ptspace->SEG=addchain(ptspace->SEG, (void *)ptseg);
         }  
      }
   }
}
/****************************************************************/
/*        Affichage des connecteurs                             */   
/****************************************************************/
void affich_connect(ptspace)
DPP_SPACE *ptspace;
{
chain_list *con_north=NULL;
chain_list *con_south=NULL;
chain_list *con_df=NULL;
chain_list *s=NULL;
DPP_CONNECTOR *con_n=NULL;
DPP_CONNECTOR *con_s=NULL;
DPP_CONNECTOR *con_d=NULL;
DPP_POSSIBILITY *p=NULL;
for(con_north=ptspace->N_CON;con_north;con_north=con_north->NEXT)
   {
   con_n=(DPP_CONNECTOR *)con_north->DATA;
   printf("-----------------------------------------------\n");
   for(s=con_n->POS;s;s=s->NEXT)
      {
      p=(DPP_POSSIBILITY *)s->DATA;
      printf("con_north NAME:%s---->ORIENT:%c posX:%ld---->posY:%ld\n",con_n->NAME,
             con_n->ORIENT, p->XCON,p->YCON);
   printf("-----------------------------------------------\n");
      }
   }
for(con_south=ptspace->S_CON;con_south;con_south=con_south->NEXT)
   {
   con_s=(DPP_CONNECTOR *)con_south->DATA;
   printf("-----------------------------------------------\n");
   for(s=con_s->POS;s;s=s->NEXT)
      {
      p=(DPP_POSSIBILITY *)s->DATA;
      printf("con_south NAME:%s--ORIENT:%c--INSNAME:%s posX:%ld--posY:%ld\n",con_s->NAME, con_s->ORIENT,ptspace->INSNAME, p->XCON,p->YCON);
   printf("-----------------------------------------------\n");
      }
   }
for(con_df=ptspace->DF_CON;con_df;con_df=con_df->NEXT)
   {
   con_d=(DPP_CONNECTOR *)con_df->DATA;
   printf("-----------------------------------------------\n");
   for(s=con_d->POS;s;s=s->NEXT)
      {
      p=(DPP_POSSIBILITY *)s->DATA;
      printf("con_df NAME:%s---->posX:%ld---->posY:%ld\n",con_d->NAME,
             p->XCON,p->YCON);
   printf("-----------------------------------------------\n");
      }
   }
}

/****************************************************************/
/*               Calcul du track capacity d'une instance        */   
/****************************************************************/
int track_capacity(fig,ptspace)
phfig_list *fig;
DPP_SPACE *ptspace;
{
int dmax=0;
chain_list *seg=NULL;
DPP_SEGMENT *segment=NULL;

for(seg=ptspace->SEG;seg;seg=seg->NEXT)
   {
   segment=(DPP_SEGMENT *)seg->DATA;
   if ((segment->X1==fig->XAB1)&&(segment->X2==fig->XAB2))
      dmax = dmax + 2;
   else
      if (((segment->X1==fig->XAB1)&&(segment->X2<fig->XAB2))||
          ((segment->X1>fig->XAB1)&&(segment->X2==fig->XAB2)))
         dmax++;
      else
         {
         printf("Error: Allow-metal2 segment in %s not valid!\n",fig->NAME);
         exit(11);
         }
   }
return(dmax);
}
/****************************************************************/
/*       tri():sert a l'utilisation de la fonction qsort        */   
/****************************************************************/
int tri(p1, p2)
long *p1;
long *p2;
{
return(*p1 - *p2);
}
/****************************************************************/
/*       tri_alim():trier les ordonnees des alim                */
/*                 afin de determiner les hauteurs des bit_slice*/   
/****************************************************************/
void tri_alim(phfig)
phfig_list *phfig;
{
phcon_list *ptcon=NULL;
int k=0, i=0;
char *vss, *vdd;
vdd=namealloc("vdd");
vss=namealloc("vss");     

for(ptcon=phfig->PHCON;ptcon;ptcon=ptcon->NEXT)
  {
  if(strncmp(vdd,ptcon->NAME,3)==0) t[k++]=ptcon->YCON;  
  else if(strncmp(vss,ptcon->NAME,3)==0) t[k++]=ptcon->YCON;  
  }
qsort(t, k, sizeof(long), tri);

}

/****************************************************************/
/* Recherche_slice_next():Recherche du bit-slice de la prochaine*/   
/*                        instance non indexee a placer.       */
/****************************************************************/
int recherche_slice_next(j, p_slice, nb, lig)
int j;
int *p_slice;
int nb;
int lig;
{
int slice2=-1;
int flag=0;
int k=0, next=0, min=0;
int i=0, ind=0;

for(i=0;i<lig;i++)
   {
   flag=0;
   for(k=0;k<nb;k++)
      {  
      if(tab[i+k][j]==NULL)
        {
        flag++;
        }
      }  
   if(flag==nb)
      {
      if(ind==0)
        {
        next=abs((*p_slice)-i);
        min=next;
        slice2=i;
        ind=1;
        }
      else if(ind!=0)
        {
        next=abs((*p_slice)-i);
        if(next < min)
          {
          slice2=i;
          min=next;
          }
        }
      }  
   }
return(slice2);
}
/****************************************************************/
/* Recherche_slice():Recherche du bit-slice pour la premiere    */   
/*                   instance non indexee a placer.             */
/****************************************************************/
int recherche_slice(j, ligne, nb)
int j;            /* Indice de la colonne */
int ligne;        /* nombre de bit_slice du circuit */
int nb;           /* nombre de bit_slice qu'occupe la cellule */
{
int slice=0;
int i=0, k=0;
int min=0;
int bas=-1, haut=-1;
int flag=0, ind=0;
int dif1=0, dif2=0;

/*Recherche d'une case vide la plus proche du milieu*/
/*dans la 1ere moitie de la colonne.*/    
for(i=0;i<ligne/2;i++)
   {
   flag=0;
   for(k=0;k<nb;k++)
      {
      if(tab[i+k][j]==NULL)
        {
        flag++;
        }
      }
   if(flag==nb)
     {
     bas=i;/*indice de bit-slice se trouvant dans la 1ere moitie */
     }     /*de la colonne.*/
   }
if(bas!=-1)
  {
  dif1=(ligne/2 - bas);
  }

/*Recherche d'une case vide la plus proche du milieu*/
/*dans la 2eme moitie de la colonne.*/    
for(i=ligne/2;i<ligne;i++)
   {
   flag=0;
   for(k=0;k<nb;k++)
      {
      if(tab[i+k][j]==NULL)
        {
        flag++;
        }
      if(ind==0)
        {
        if(flag==nb)
          {
          haut=i;
          min=i;
          ind=1;
          }
        }
      else if(ind!=0)
        {
        if(i < min)
          {  
          haut=i;
          min=i;
          }  
        }
      }
   }
if(haut !=-1)/*il existe autant de cases vides que nb*/
  {          /*dans la 2eme moitie du haut.*/
  dif2=(haut - ligne/2);
  }

if(dif1!=0 && dif2!=0)
  {
  if((dif1 < dif2) || (dif1==dif2))
    {
    slice=bas;
    }
  else if(dif2 < dif1)
    {
    slice=haut;
    }
  }
else if(dif1==0) 
  { 
  slice=haut;/*Aucune case disponible dans la moitie du bas*/
  } 
else if(dif2==0) 
  { 
  slice=bas;/*Aucune case disponible dans la moitie du haut*/
  } 
return(slice);
}

/****************************************************************/
/*  Fonction realisant le placement des instances a index pair */   
/****************************************************************/
void place_pair(i,nb,insname,ptins,ptc,ptlo,phfig,index,compt,lig)
int i;
int nb;
char  *insname;
loins_list *ptins;
DPP_GET_INDEX_LIST *ptc;
lofig_list *ptlo;
phfig_list *phfig;
int index;
int compt;
int lig;
{
DPP_SPACE *ptspace=NULL;
locon_list *locon=NULL;
long ymin=0, ymax=0;
int k=0, cpt;
long haut=0;
char *vss, *vdd;

vdd=namealloc("vdd");
vss=namealloc("vss");     

/*Verifier l'aboutabilite nord et sud avant de placer*/
abut_N('P', ptins,phfig,nb,i,ptc->INDEX,lig);
abut_S('P', ptins,phfig,i,ptc->INDEX,lig);

ymin=ord_alim(phfig);
for(k=0, cpt=0;k<nb;k++, cpt++) 
   {
   if (tab[i+k][ptc->INDEX]==NULL)
      {
       ptspace=makespace(insname,ptins->FIGNAME,ptc->UPFIG,ptc->UPINS, 
                          width(phfig), nb, i+k, ptc->INDEX);
       tab[i+k][ptc->INDEX]=ptspace;
       for(;t[cpt+1]==t[cpt];cpt++);
       haut=(t[cpt+1] - t[cpt]);/*calcul de la hauteur du bit slice*/    
       ptspace->HEIGHT=haut;
       seg(k,haut,phfig,ptspace);
       ptspace->TRACK_CAPACITY=track_capacity(phfig, ptspace); 
       ymax=(ymin + haut);
       for(locon=ptins->LOCON;locon;locon=locon->NEXT)
          {
           if((strncmp(vdd,locon->NAME,3)!=0) && (strncmp(vss,locon->NAME,3)!=0)) 
           {
           cree_con(index,k, ymin, ymax, compt, ptlo, ptspace,
                    phfig, locon, locon->SIG,i, ptc->INDEX);
           }
          }
      }
   else
      {
       printf("Space [%d,%d] is already full!\n",i+k,ptc->INDEX);
       exit(1);
      }
   ymin=ymax;
   }
}
/****************************************************************/
/* Fonction realisant le placement des instances a index impair */   
/****************************************************************/
void place_impair(i,nb,insname,ptins,ptc,ptlo,phfig,index,compteur,lig)
int i;
int nb;
char  *insname;
loins_list *ptins;
DPP_GET_INDEX_LIST *ptc;
lofig_list *ptlo;
phfig_list *phfig;
int index;
int compteur;
int lig;
{
DPP_SPACE *ptspace=NULL;
locon_list *locon=NULL;
int k=0, cpt=0, compt=0;
long ymin=0, ymax=0;
long haut=0;
char *vss, *vdd;

vdd=namealloc("vdd");
vss=namealloc("vss");     

/*Verifier l'aboutabilite nord et sud avant de placer*/
abut_N('I', ptins,phfig,nb,i,ptc->INDEX,lig);
abut_S('I', ptins,phfig,i,ptc->INDEX,lig);

ymin=ord_alim(phfig);
for(k=(nb-1), compt, cpt=0;k>=0;k--, compt++, cpt++) 
   {
   if (tab[i+compt][ptc->INDEX]==NULL)
      {
      ptspace=makespace(insname,ptins->FIGNAME,ptc->UPFIG,
                        ptc->UPINS, width(phfig), nb,
                        i+compt, ptc->INDEX);
       tab[i+compt][ptc->INDEX]=ptspace;
       for(;t[cpt+1]==t[cpt];cpt++);
       haut=(t[cpt+1] - t[cpt]);/*hauteur du bit slice*/    
       ptspace->HEIGHT=haut;
       ymax=(ymin + haut);
       seg(k,haut,phfig,ptspace);
       ptspace->TRACK_CAPACITY=track_capacity(phfig, ptspace); 
       for(locon=ptins->LOCON;locon;locon=locon->NEXT)
          {
           if((strncmp(vdd,locon->NAME,3)!=0) && (strncmp(vss,locon->NAME,3)!=0)) 
           {
           cree_con(index,k, ymin, ymax, compt, ptlo, ptspace,phfig,
                    locon, locon->SIG, i, ptc->INDEX);
           }
          }
       }
   else
      {
       printf("Space [%d,%d] is already full!\n",i+compt,ptc->INDEX);
       exit(1);
      }
   ymin=ymax;
   }
}
/****************************************************************/
/*  place_next():Placement de l'instance la plus connectee.     */   
/****************************************************************/
DPP_GET_INDEX_LIST *place_next(ptlo,ptins,ptindex,p_slice,car,flag,lig,col)
lofig_list *ptlo;
loins_list *ptins;
DPP_GET_INDEX_LIST *ptindex;
int *p_slice;
int car, flag, lig, col;
{
phfig_list *phfig=NULL;
char *s=NULL;
char *upname=NULL;
char *InsName=NULL;
DPP_GET_INDEX_LIST *ptc=NULL, *prev=NULL, *del=NULL, *pt=NULL;
int i=0, nb=0, slice2=-1;
int compt=0;
int index=0;
int mask=1;
long placed=1;

s=strchr(ptins->INSNAME,car);
upname=namealloc(extract(ptins->INSNAME,car));
if(s!=NULL)
  {
  InsName=namealloc(s+1);
  for(prev=NULL,ptc=ptindex; ptc; prev=ptc, ptc=ptc->NEXT) 
  if ((InsName == ptc->INSNAME) && (upname==ptc->UPINS)) break;

  if(ptc!=NULL)
    {
    phfig=getphfig(ptins->FIGNAME,'P');
    nb=nb_cases(phfig);
    tri_alim(phfig);
    slice2=recherche_slice_next(ptc->INDEX,p_slice,nb,lig);

    (*p_slice)=slice2;
    if(slice2!=-1) /*On a trouve la case qu'occupera ptins */
      {
      if(flag==LSB) 
        {
         i=slice2;          /*extraction de l'index */
        }
      else if(flag==MSB) 
        {
         i=((lig-1)-slice2);  /*extraction de l'index */
        }
      if((i & mask)==0) /*bit slice pair*/
        {
        place_pair(i,nb,s+1,ptins,ptc,ptlo,phfig,index,compt,lig);
        ptins->USER=addptype(ptins->USER,(long)placed,(void *)placed);
        del=ptc;
        ptc=ptc->NEXT;
        if(prev!=NULL) prev->NEXT=ptc;
        else ptindex=ptc;
     
        mbkfree((void *)del); 
        }
      else if((i & mask)==1) /*bit slice pair*/
        {
        place_impair(i,nb,s+1,ptins,ptc,ptlo,phfig,index,compt,lig);
        ptins->USER=addptype(ptins->USER,(long)placed,(void *)placed);
        del=ptc;
        ptc=ptc->NEXT;
        if(prev!=NULL) prev->NEXT=ptc;
        else ptindex=ptc;
             
        mbkfree((void *)del); 
        }
      }
    else printf("Unable to place %s\n, not available empty space in column",ptins->INSNAME);
    }
  }
return(ptindex);
}
/****************************************************************/
/*  place_init():Placement de la premiere instance non indexee  */   
/****************************************************************/
DPP_GET_INDEX_LIST *place_init(ptlo,ptins, ptindex, p_slice, car, flag, lig, col)
lofig_list *ptlo;
loins_list *ptins;
DPP_GET_INDEX_LIST *ptindex;
int *p_slice;
int car, flag, lig, col;
{
phfig_list *phfig=NULL;
char *s=NULL;
char *upname=NULL;
char *InsName=NULL;
DPP_GET_INDEX_LIST *ptc=NULL, *prev=NULL, *del=NULL;
int i=0, nb=0, slice=0;
int compt=0;
int index=0;
int mask=1;
long placed=1;

s=strchr(ptins->INSNAME,car);
upname=namealloc(extract(ptins->INSNAME,car));
if(s!=NULL)
  {
  InsName=namealloc(s+1);
  for(prev=NULL,ptc=ptindex; ptc; prev=ptc, ptc=ptc->NEXT) 
  if ((InsName == ptc->INSNAME) && (upname == ptc->UPINS)) break;

  if(ptc!=NULL)
    {
    phfig=getphfig(ptins->FIGNAME,'P');
    nb=nb_cases(phfig);
    tri_alim(phfig);
    (*p_slice)=recherche_slice(ptc->INDEX, lig, nb);
  
    if((*p_slice)!=-1) /*On a trouve la case qu'occupera ptins */
      {
      if(flag==LSB) 
        {
         i=(*p_slice);          /*extraction de l'index */
        }
      else if(flag==MSB) 
        {
         i=((lig-1)-(*p_slice));  /*extraction de l'index */
        }
      if((i & mask)==0) /*bit slice pair*/
        {
        place_pair(i,nb,s+1,ptins,ptc,ptlo,phfig,index,compt,lig);
        ptins->USER=addptype(ptins->USER,(long)placed,(void *)placed);
        del=ptc;
        ptc=ptc->NEXT;
        if(prev!=NULL) prev->NEXT=ptc;
        else ptindex=ptc;
     
        mbkfree((void *)del); 
        }
      else if((i & mask)==1) /*bit slice pair*/
        {
        place_impair(i,nb,s+1,ptins,ptc,ptlo,phfig,index,compt,lig);
        ptins->USER=addptype(ptins->USER,(long)placed,(void *)placed);
        del=ptc;
        ptc=ptc->NEXT;
        if(prev!=NULL) prev->NEXT=ptc;
        else ptindex=ptc;
             
        mbkfree((void *)del); 
        }
      }
    else printf("Unable to place %s, not available empty space in column!\n",ptins->INSNAME);
    }
  }
return(ptindex);
}
/****************************************************************/
/*  Fonction realisant le placement des instances d'une colonne */   
/****************************************************************/
DPP_GET_INDEX_LIST *place(ptlo,ptindex,lig,col,car,flag)
lofig_list *ptlo;
DPP_GET_INDEX_LIST *ptindex;
int lig,col;
char car;
int flag;
{
phfig_list *ptfig=NULL;
phfig_list *phfig=NULL;
phfig_list *phfigins=NULL;
phfig_list *ptph=NULL;
loins_list *ptins=NULL;
locon_list *locon=NULL;
DPP_GET_INDEX_LIST *ptc_cur=NULL, *ptc_prev=NULL, *ptc_del=NULL;
DPP_GET_INDEX_LIST *ptaux=NULL;
DPP_GET_INDEX_LIST *ptc=NULL;
DPP_SPACE *ptspace=NULL;
long ymin=0, ymax=0, haut;
int compt=0, cpt=0;
int nb=0;
int i=0, k=0;
int index=0;
int mask=1;
char *s=NULL;
char *InsNameIndex;
char *name=NULL;
char *upname=NULL;
char *vdd, *vss;
long placed=1;

vdd = namealloc("vdd");
vss = namealloc("vss");     

ptdatapath = (DPP_DATAPATH *)mbkalloc(sizeof(struct ADPP_DATAPATH));
ptdatapath->SIG = NULL;
ptdatapath->CON = NULL;

for (ptins=ptlo->LOINS;ptins;ptins=ptins->NEXT)
    {
    name = extract(ptins->INSNAME,car);/* extraction du nom precedent
                                          le caractere MBK_SEPAR     */
    if (name==0) /*instance du 1er niveau appartenant au CATAL*/
       {
       for(ptc_prev=NULL,ptc_cur=ptindex;
          (ptc_cur && (ptins->INSNAME != ptc_cur->INSNAME));
          ptc_prev=ptc_cur, ptc_cur=ptc_cur->NEXT); 
       if(ptc_cur!=NULL){
        phfig=getphfig(ptins->FIGNAME,'P');
        /*viewphfig(phfig);*/
        nb=nb_cases(phfig);/* nombre de bit slices qu'occupe la cellule */
        /*viewphfig(phfig);*/
        tri_alim(phfig);/*les ordonnees des alim sont triees dans un tableau */
        /*viewphfig(phfig);*/
        ymin=ord_alim(phfig);
        /*viewphfig(phfig);*/

        for(k=0, cpt=0;k<nb;k++, cpt++) {
         ptspace=makespace(ptins->INSNAME,ptins->FIGNAME,ptlo->NAME,ptlo->NAME,
                           width(phfig),nb, k, ptc_cur->INDEX);
        /*viewphfig(phfig);*/
         tab[k][ptc_cur->INDEX]=ptspace;
         for(;t[cpt+1]==t[cpt];cpt++);
         haut=(t[cpt+1] - t[cpt]);/*calcul de la hauteur du bit slice*/        
         ptspace->HEIGHT=haut;
         ymax=(ymin + haut);
         seg(k,haut,phfig,ptspace);/*segments horizontaux en TALU2*/
         ptspace->TRACK_CAPACITY=track_capacity(phfig, ptspace); 
         for(locon=ptins->LOCON;locon;locon=locon->NEXT) {
         if((strncmp(vdd,locon->NAME,3)!=0) && (strncmp(vss,locon->NAME,3)!=0)) 
            {
            cree_con(index,k, ymin, ymax, compt, ptlo, ptspace,
                     phfig, locon, locon->SIG, i,ptc_cur->INDEX );
            }
           }
         ymin=ymax;
         }
       ptins->USER=addptype(ptins->USER,(long)placed,(void *)placed);
        ptc_del=ptc_cur;
        ptc_cur=ptc_cur->NEXT;
        if(ptc_prev!=NULL) ptc_prev->NEXT=ptc_cur;
        else ptindex=ptc_cur;
        mbkfree((void *)ptc_del); 
       }
       else fprintf(stdout,"ERROR...\n");
     }
     /*instance du 1er niveau n'appartenant pas au CATAL */ 
     else  {

     /* Placement de l'instance suivant son index */
          upname=namealloc(extract(ptins->INSNAME,car));
          s=strchr(ptins->INSNAME, car );
          InsNameIndex=namealloc(s+1); 
          if(test_insname(InsNameIndex) !=-1)
            { 
             compt=0;
             if(flag==LSB) 
               {
                i=test_insname(InsNameIndex);     /*extraction de l'index */
               }
             if(flag==MSB) 
               {
                i=((lig-1)-test_insname(InsNameIndex));  /*extraction de l'index */
               }
              for(ptc_prev=NULL,ptc_cur=ptindex; ptc_cur;
                  ptc_prev=ptc_cur, ptc_cur=ptc_cur->NEXT) 
               if ((InsNameIndex == ptc_cur->INSNAME) && (upname == ptc_cur->UPINS)) break;
               if(ptc_cur!=NULL){

               phfig=getphfig(ptins->FIGNAME,'P');
               nb=nb_cases(phfig);/* nombre de bit slices qu'occupe la cellule */
               tri_alim(phfig);/*ordonnees des alim sont triees dans un tableau */

               if((i & mask)==0) /* Instances a index pairs */
                 {
                 place_pair(i,nb,s+1,ptins,ptc_cur,ptlo,phfig,index,compt,lig);

                 ptins->USER=addptype(ptins->USER,(long)placed,(void *)placed);
                 ptc_del=ptc_cur;
                 ptc_cur=ptc_cur->NEXT;
                 if(ptc_prev!=NULL) ptc_prev->NEXT=ptc_cur;
                 else ptindex=ptc_cur;
                 mbkfree((void *)ptc_del); 
                 }
              else if((i & mask)==1)/* Instances a index impairs */
                     {
                     place_impair(i,nb,s+1,ptins,ptc_cur,ptlo,phfig,index,compt,lig);

                     ptins->USER=addptype(ptins->USER,(long)placed,(void *)placed);
                     ptc_del=ptc_cur;
                     ptc_cur=ptc_cur->NEXT;
                     if(ptc_prev!=NULL) ptc_prev->NEXT=ptc_cur;
                     else ptindex=ptc_cur;
             
                     mbkfree((void *)ptc_del); 
                    }
               }
           }/* fin de placement de toutes les instance indexees*/
       }/*fin test instance du 2eme niveau*/
  } 
return(ptindex);
}
/****************************************************************/
/*   rech_con():recherche du connecteur DATA                    */
/****************************************************************/
locon_list *rech_con(pt, locon)
loins_list *pt;
locon_list *locon;
{
phfig_list *ptfig=NULL;
phref_list *ptref=NULL;
locon_list *locon_save=NULL;
char       *name=NULL;
char       *ref_con;

ref_con=namealloc("ref_con");
ptfig=getphfig(pt->FIGNAME,'P');
for(ptref=ptfig->PHREF;ptref;ptref=ptref->NEXT)
   {
   if(ptref->FIGNAME ==ref_con)
     {
      name=extract(ptref->NAME,'_');
      if(namealloc(name)==locon->NAME)
        {
        locon_save=locon;
        break;
        }
     }
   }
return(locon_save);
}
/****************************************************************/
/*      max_connected():Renvoie le pointeur sur l'instance la   */
/*                      plus connectee a ptins.                 */
/****************************************************************/
loins_list *max_connected(ptins,ptlo,p_connected)
loins_list *ptins;
lofig_list *ptlo;
int        *p_connected;
{
loins_list *pt=NULL;
loins_list *pt_save=NULL;
locon_list *locon1=NULL;
locon_list *locon2=NULL;
locon_list *ptlocon1=NULL;
locon_list *ptlocon2=NULL;
phfig_list *ptfig=NULL;
char *vss, *vdd;
int  cpt=0;
int  max=0;

vdd=namealloc("vdd");
vss=namealloc("vss");     

*p_connected=0;

for(pt=ptlo->LOINS;pt;pt=pt->NEXT)
   {
   if(pt->USER==NULL && (ptins->INSNAME!=pt->INSNAME))
     {
     cpt=0;
     for(locon1=pt->LOCON;locon1;locon1=locon1->NEXT)
        {
        if(strncmp(vdd,locon1->NAME,3)!=0 && strncmp(vss,locon1->NAME,3)!=0){
        ptlocon1=rech_con(pt, locon1);/*Connecteur DATA seulement*/
        for(locon2=ptins->LOCON;locon2;locon2=locon2->NEXT)
           {
           if(strncmp(vdd,locon2->NAME,3)!=0 && strncmp(vss,locon2->NAME,3)!=0){
           ptlocon2=rech_con(ptins, locon2);
           if(ptlocon1!=NULL && ptlocon2!=NULL){
           if(ptlocon1->SIG->INDEX==ptlocon2->SIG->INDEX)
             {
             cpt++;
             }
            }
           }
          }
         }
        }
     if(cpt > max)
       {
       max=cpt;
       pt_save=pt;
       *p_connected=1;
       }
     }
   }
return(pt_save);
}
/****************************************************************/
/*       tri():sert a l'utilisation de la fonction qsort        */   
/****************************************************************/
int tri_chaine(p1, p2)
char **p1;
char **p2;
{
return(strcmp(*p1,*p2));
}
/****************************************************************/
/*       tri_connector():tri des noms des connecteurs DF        */
/*                 afin de determiner leur nombre.              */   
/****************************************************************/
int tri_connector(phfig)
phfig_list *phfig;
{
phref_list *ptref=NULL;
int k=0, i=0;
char *vss, *vdd, *nwell;
char *name=NULL;
vdd=namealloc("vdd");
vss=namealloc("vss");     
nwell=namealloc("nwell");     

for(ptref=phfig->PHREF;ptref;ptref=ptref->NEXT)
   {
   if(strncmp(vdd,ptref->NAME,3) && strncmp(vss,ptref->NAME,3)
                                 && strncmp(nwell,ptref->NAME,4))
     {
     name=extract(ptref->NAME,'_');
     g[k++]=name;  
     }
   }
/*for(i=0;i<k;i++)
   {
   printf("g[%d]=%s (0x%x)\n",i,g[i], g[i]);
   }*/
qsort(g, k, sizeof(char*), tri_chaine);
return(k);
}
/****************************************************************/
/*if_connected():Chercher si la premiere instance non indexee    */   
/*              est connectee a une instance indexee deja placee.*/
/****************************************************************/
int if_connected(ptins, p_slice, lig, col)
loins_list *ptins;
int *p_slice;
int lig, col;
{
int i=0, j=0;
int cpt=0;
int max=0;
int ind=1;
DPP_SPACE        *ptspace=NULL;
struct chain *sig=NULL;
DPP_SIGNAL        *signal=NULL;
locon_list    *locon=NULL;
char *vss, *vdd;

vdd=namealloc("vdd");
vss=namealloc("vss");

for(i=0;i<lig;i++)
   {
   for(j=1;j<=col;j++)
      {
      cpt=0;
      ptspace=tab[i][j];
      if(tab[i][j]!=NULL)
        {
        for(sig=ptspace->SIG;sig;sig=sig->NEXT)
           {
           signal=(DPP_SIGNAL *)sig->DATA;
           for(locon=ptins->LOCON;locon;locon=locon->NEXT)
              {
              if(strncmp(vdd,locon->NAME,3)!=0 && strncmp(vss,locon->NAME,3)!=0)
                {
                if(locon->SIG->INDEX==signal->index)
                  {
                  cpt++;
                  }
                }
              }
           }
         if(cpt > max)
           {
           max=cpt;
           (*p_slice)=ptspace->I;
           ind=0;
           }
        }
      }
   }
return(ind);
}
/****************************************************************/
/*     connectivity():Calcul de la connectivite d'une instance. */   
/****************************************************************/
int connectivity(ptins)
loins_list *ptins;
{
phfig_list *ptfig=NULL;
phcon_list *ptcon=NULL;
int nbre=0;
int k=0;
int i=0;
char *vss, *vdd;
char *name=NULL;
char *nom=NULL;

vdd=namealloc("vdd");
vss=namealloc("vss");

ptfig=getphfig(ptins->FIGNAME,'P');
k=tri_connector(ptfig);
nbre=(k>0)?1:0;

/*for(i=0;i<k;i++)
   {
   printf("g[%d]=%s (0x%x)\n",i,g[i], g[i]);
   }*/
for(i=1;i<k;i++)
   {
   if(strcmp(g[i-1],g[i])!=0)
      {
      nbre++;
      }
   }

for(ptcon=ptfig->PHCON;ptcon;ptcon=ptcon->NEXT)
   {
   if(strncmp(vdd,ptcon->NAME,3) && strncmp(vss,ptcon->NAME,3))
     {
     if(ptcon->ORIENT!='S' && ptcon->ORIENT!='N')
       {
       nbre++;
       }
     }
   }

return(nbre);
}
/****************************************************************/
/*    place_branch():Fonction  de placement des instances       */
/*                   d'une branche.                             */
/****************************************************************/
DPP_GET_INDEX_LIST *place_branch(ptins,ptlo,ptindex,slice,car,flag,lig,col)
loins_list *ptins;
lofig_list *ptlo;
DPP_GET_INDEX_LIST *ptindex;
int slice;
int car, flag;
int lig, col;
{
loins_list *pt_next=NULL;
DPP_GET_INDEX_LIST *ptindex1=NULL;
DPP_GET_INDEX_LIST *pt=NULL;
int connected=1;

ptindex1=place_next(ptlo,ptins,ptindex,&slice,car,flag,lig,col);

while(connected==1)
     {
     pt_next=max_connected(ptins,ptlo,&connected);
     if(connected==1)
       {
       ptindex1=place_branch(pt_next,ptlo,ptindex1,slice,car,flag,lig,col);
       }
     }
return(ptindex1);
}

/****************************************************************/
/*    place_no_index():Fonction principal de placement des      */   
/*                     instances non indexees.                  */
/****************************************************************/
void place_no_index(ptlo,ptindex,car,flag,lig,col)
lofig_list *ptlo;
DPP_GET_INDEX_LIST *ptindex;
int car, flag;
int lig, col;
{
int max=0;
int slice=0;
int ind=-1;
int next=1;
loins_list *ptins=NULL;
loins_list *pt_save=NULL;
loins_list *pt_next=NULL;
int connected=1;
DPP_GET_INDEX_LIST *ptindex1=NULL;
DPP_GET_INDEX_LIST *pt=NULL;
 
while(next==1)
     {
     connected=1;
     max=0;
     pt_save=NULL;
     for(ptins=ptlo->LOINS;ptins;ptins=ptins->NEXT)
        {
        if(ptins->USER==NULL)/*Si l'instance n'est pas taguee c-a-d non placee*/
          {
          if(connectivity(ptins) > max)
            {
            pt_save=ptins;/*Pointeur sur l'instance a haute connectivite*/
            max=connectivity(ptins);
            }
          }
        }
     if(pt_save!=NULL)
       {
        next=1;
        printf("FIRST INSTANCE:%s\n",pt_save->INSNAME);
        /*L'instance est-elle connectee a une instance indexee deja placee?*/
        ind=if_connected(pt_save, &slice, lig, col);
        if(ind==1)
          {
          ptindex=place_init(ptlo,pt_save,ptindex,&slice,car,flag,lig,col);
          }
        else if(ind!=1)
         {
         ptindex=place_next(ptlo,pt_save,ptindex,&slice,car,flag,lig,col);
         }

        while(connected==1)
             {
             pt_next=max_connected(pt_save,ptlo,&connected);
             if(pt_next !=NULL && connected==1)
               {
               ptindex=place_branch(pt_next,ptlo,ptindex,slice,car,flag,lig,col);
               }
             }  
        }
        else if(pt_save==NULL) next=0;
     }
}
/****************************************************************/
/*     verification                                             */   
/****************************************************************/
void verif_tableau(lig, col)
int lig;
int col;
{
DPP_SPACE *ptspace=NULL;
int i=0, j=0;
chain_list *con=NULL, *pos=NULL;
DPP_CONNECTOR *con_n=NULL;
DPP_POSSIBILITY *pos_n=NULL;

for(j=1;j<=col+1;j++)
   {
   for(i=0;i<lig;i++)
      {
      ptspace=tab[i][j];
      if(tab[i][j]!=NULL)
        {
        for(con=ptspace->N_CON;con;con=con->NEXT)
           {
           printf("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
           con_n=(DPP_CONNECTOR *)con->DATA;
           printf("INSTANCE:%s\n",ptspace->INSNAME);
           printf("con_n:%s\n",con_n->NAME);
           for(pos=con_n->POS;pos;pos=pos->NEXT)
              {
              pos_n=(DPP_POSSIBILITY *)pos->DATA;
              printf("XCON:%ld   YCON:%ld\n",pos_n->XCON,pos_n->YCON);
              }
           }
        }
      }
   }
}
/****************************************************************/
/*     verification des signaux                                 */   
/****************************************************************/
void verif_sig(lig, col)
int lig;
int col;
{
int i, j;
DPP_SPACE *ptspace=NULL;
chain_list *sig=NULL;
chain_list *con=NULL;
DPP_SIGNAL *sig_n=NULL;
DPP_CONNECTOR *conn=NULL;

for(j=1;j<=col;j++)
   {
   for(i=0;i<=lig;i++)
      {
      ptspace=tab[i][j];
      if(tab[i][j]!=NULL)
        {
printf("****************************************************************\n");
printf("               INS:%s\n",ptspace->INSNAME);
        for(sig=ptspace->SIG;sig;sig=sig->NEXT) 
           {
printf("----------------------------------------------------------------\n");
           sig_n=(DPP_SIGNAL *)sig->DATA;
printf(" INDEX:%ld  WIDTH:%d  HEIGHT:%d\n",sig_n->index,sig_n->width,sig_n->height);
           for(con=sig_n->CON;con;con=con->NEXT)
              {
              conn=(DPP_CONNECTOR *)con->DATA;
printf("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
           printf(" con :%s COL:%d LIN:%d\n",conn->NAME,conn->COL,conn->LIN);
              }
           }
        }
      }
   }
}
/****************************************************************/
/*     verification des signaux dans DPP_DATAPATH                   */   
/****************************************************************/
void verif_datapath()
{
chain_list *signal=NULL;
chain_list *column=NULL;
DPP_SIGNAL *sig=NULL;
int colo=0;

for(signal=ptdatapath->SIG;signal;signal=signal->NEXT)
   {
   printf("***********************************************************\n");
   sig=(DPP_SIGNAL *)signal->DATA;
   printf("NAME:%s\n",sig->NAME);
   printf("INDEX:%ld  WIDTH:%d TMP_WIDTH:%d MIN_COL:%d TMP_MIN_COL:%d\n"
          ,sig->index,sig->width,sig->TMP_width,sig->MIN_COL,sig->TMP_MIN_COL);
   for(column=sig->COL;column;column=column->NEXT)
      {
      printf("--------------------------------------------------\n");
      colo=(int)column->DATA;
      printf("COL:%d\n",colo);
      }
   }
}
/****************************************************************/
/*     verification des segments                                */   
/****************************************************************/
void verif_seg(lig, col)
int lig;
int col;
{
int i, j;
DPP_SPACE *ptspace=NULL;
chain_list *seg=NULL;
DPP_SEGMENT *seg_n=NULL;

for(j=1;j<=col;j++)
   {
   for(i=0;i<lig;i++)
      {
      ptspace=tab[i][j];
      if(tab[i][j]!=NULL)
        {
        for(seg=ptspace->SEG;seg;seg=seg->NEXT) 
           {
printf("****************************************************************\n");
           seg_n=(DPP_SEGMENT *)seg->DATA;
           printf("INS:%s MERE:%s X1:%ld Y1:%ld X2:%ld Y2:%ld\n",ptspace->INSNAME,ptspace->UPINS,seg_n->X1, seg_n->Y1, seg_n->X2, seg_n->Y2);
printf("****************************************************************\n");
           }
        }
      }
   }
}

/****************************************************************/
/*      VISU de la liste des connecteurs dans DPP_DATAPATH          */   
/****************************************************************/
void verif_data()
{
chain_list *con=NULL;
DPP_CONNECTOR *connect=NULL;
DPP_POSSIBILITY *pos=NULL;
chain_list *c_pos=NULL;

for(con=ptdatapath->CON;con;con=con->NEXT)
   {
   connect=(DPP_CONNECTOR *)con->DATA;
printf("****************************************************************\n");
printf("name:%s   LIN:%d   COL:%d   ORIENT:%c \n",connect->NAME, connect->LIN,
                                                  connect->COL, connect->ORIENT);
  for(c_pos=connect->POS;c_pos;c_pos=c_pos->NEXT)
     { 
   pos=(DPP_POSSIBILITY *)c_pos->DATA;
   printf("X:%ld   Y:%ld LAYER:%c\n",pos->XCON,pos->YCON, pos->LAYER); 
     } 
   }
}
