/****************************************************************************/
/*                                                                          */
/*                      Chaine de CAO & VLSI   Alliance                     */
/*                                                                          */
/*    Produit : synthetiseur logique                                        */
/*    Fichier : sl_mbk.c                                                    */
/*                                                                          */
/*    (c) copyright 1991 Laboratoire MASI equipe CAO & VLSI                 */
/*    Tous droits reserves                                                  */
/*    Support : e-mail cao-vlsi@masi.ibp.fr                                 */
/*                                                                          */
/*    Auteur(s) : Burgun L. & Allegre P.                le : 29/09/1991     */
/*                                                                          */
/*    Modifie par :                                     le : ../../....     */
/*    Modifie par :                                     le : ../../....     */
/*    Modifie par :                                     le : ../../....     */
/*                                                                          */
/****************************************************************************/
#include MUT_H
#include MLO_H
#include LOG_H
#include BEH_H
#include "../compil/lax_param.h"
#include "../synthe/sl_type.h"
#include "../mapping/types.h"
#include "../mapping/oper.h"
#include "../mapping/util.h"
#include "../mapping/compile.h"
#include "sl_mbk.h"

int Surface(name)
char *name;
{
cellList *cell;
for(cell = mappSys->ptcell; cell; cell = cell->NEXT)
   if (cell->nom == name)
      if (searchGeneric(cell, name, "area") != 0)
         return searchGeneric(cell, name, "area");
      else
         return searchGeneric(cell, name, "surface");
}

/*-------------------------------------------------------------------------
nameInst        : remplace le blanc par un _ 
---------------------------------------------------------------------------
retour          : un pointeur de chaine de caracteres.
---------------------------------------------------------------------------*/
char *nameInst(name)
char *name;
{
char *name1;
int i;
int length = strlen(name);

name1 = (char *)  mbkalloc (length+2);
strcpy(name1,name);
i = 0;
while (name1[i] != '\0')
   {
   if (name1[i] == ' ')
      name1[i] = '_';
   i++;
   }   
name = namealloc(name1);
#if MACHINE != pc
   mbkfree((void *)name1);
#endif

return(name);
}

/*------------------------------------------------------------------------------
genMBKBeh	 : genere une lofig a partir d'une befig "structurelle" 
-------------------------------------------------------
parametres 	 : une befig.
-------------------------------------------------------
return 		 : une lofig.
------------------------------------------------------------------------------*/
void genMBKBeh(beh,capa)
befig_list *beh;
short capa;
{
long indexMax = 0;
losig_list *sigBidon, *losig;
char *inv = namealloc("not1");
int numberCell, numberCone;
lofig_list *fig = (lofig_list *)NULL;
losig_list *signal = (losig_list *)NULL; 
int index = 1;
bepor_list *bp,*bp2;
beout_list *out;
bereg_list *reg;
beaux_list *aux;
bebus_list *bus;
bebux_list *bux;
cellList *cell;
chain_list *ptChain;
pTH losigHash;
sig *sigAux;
virtuelList *virt;
int erreur = 0;
chain_list *supp = (chain_list *)NULL, *aSupp;
ptype_list *regCell = (ptype_list *)NULL, *bdCell = (ptype_list *)NULL;
cellList *cellLo;
ptype_list *cellAutre, *cellMod;
biabl_list *b1abl, *b2abl;


	/* variables pour les statistiques */
loins_list *inst;
chain_list *mod;
int countMod = 0;
int totalInst = 0;
int totalSurf = 0;
int numberNot = 0;
char *nomFig;

nomFig = (char *)genNAME("%s",SL_FILEOUT);

	/* creation de la table de hashage signal -> losig_list */
losigHash = createTH(1000);

		/* creation de la lofig */
fig = addlofig(nomFig);
printf("\n");

		/* creation des connecteurs et des signaux */
		/* les signaux */

   reg = beh->BEREG;
   while (reg)
   {
      sigAux = (sig *)testObj(reg->NAME,'s');
      if (capa && sigAux)
         signal = addlosig(fig,index,addchain((chain_list *)NULL,(void *)gensym("auxreg",index)), 'I',(float)sigAux->capa/1000);
      else
         signal = addlosig(fig,index,addchain((chain_list *)NULL,(void *)gensym("auxreg",index)), 'I',0.0);
      index++;
      addTH(losigHash,reg->NAME,signal);
      reg = reg->NEXT;
   }
   aux = beh->BEAUX;
   while (aux)
   {
      sigAux = (sig *)testObj(aux->NAME,'s');
      virt = (virtuelList *)testObj(aux->NAME,'v');
      if (ATOM(aux->ABL) &&
       ((signal = (losig_list *)searchTH(losigHash,VALUE_ATOM(aux->ABL)))
                != (losig_list *) VIDETH))
      {
         addTH(losigHash,aux->NAME,signal);
      }
      else
      {
	if (capa && ((int)virt > 1))
	   if (sigAux)
              signal = addlosig(fig,index++,addchain((chain_list *)NULL,(void *)aux->NAME),'I',(float)sigAux->capa/1000);
	   else
              signal = addlosig(fig,index++,addchain((chain_list *)NULL,(void *)aux->NAME),'I',(float)virt->capa/1000);
	else
           signal = addlosig(fig,index++,addchain((chain_list *)NULL,(void *)aux->NAME),'I',0.0);
        addTH(losigHash,aux->NAME,signal);
      }
      aux = aux->NEXT;
   }

   bux = beh->BEBUX;
   while (bux)
   {
      sigAux = (sig *)testObj(bux->NAME,'s');
      virt = (virtuelList *)testObj(bux->NAME,'v');

	if (capa && ((int)virt > 1))
	   if (sigAux)
              signal = addlosig(fig,index++,addchain((chain_list *)NULL,(void *)bux->NAME),'I',(float)sigAux->capa/1000);
	   else
              signal = addlosig(fig,index++,addchain((chain_list *)NULL,(void *)bux->NAME),'I',(float)virt->capa/1000);
	else
           signal = addlosig(fig,index++,addchain((chain_list *)NULL,(void *)bux->NAME),'I',0.0);
        addTH(losigHash,bux->NAME,signal);
      bux = bux->NEXT;
   }

		/* les connecteurs */

   bp = (bepor_list *)reverse((chain_list *)beh->BEPOR);
   beh->BEPOR = bp;
   do
   {
      sigAux = (sig *)testObj(bp->NAME,'s');
      if (bp->DIRECTION == 'O')
      {
      beout_list *bidule;

       /* recherche du signal de sortie dans BEOUT */
       out = beh->BEOUT;
       while (out && (out->NAME != bp->NAME)) out = out->NEXT;
       if (out) bidule = out;

       if (out && ATOM(bidule->ABL))
       {
	  bp2 = beh->BEPOR;
	  while (bp2 && (bp2->NAME != VALUE_ATOM(bidule->ABL))) bp2 = bp2->NEXT;
	  if (bp2 && bp2->DIRECTION == 'I')
	  {
	    printf("\nNetlist generation : Error - output connector connected to input connector\n");
	    printf("                     Connectors : %s - %s\n",bidule->NAME,VALUE_ATOM(bidule->ABL));
	    erreur = 1;
	  }
       }

       /* recherche d'une sortie egale */
       out = beh->BEOUT;
       do
         if (out && ATOM(out->ABL) && VALUE_ATOM(out->ABL) != nameLow &&
	     (bidule->NAME != out->NAME) &&
	     (searchTH(losigHash,out->NAME) != VIDETH) &&
             (VALUE_ATOM(bidule->ABL) == VALUE_ATOM(out->ABL)))
         {
	    printf("\nNetlist generation : Error - 2 connectors linked together\n");
	    printf("                     Connectors : %s - %s -> %s\n",bidule->NAME,out->NAME,VALUE_ATOM(out->ABL));
	    erreur = 1;
         }
       while (out = out->NEXT);

       if (ATOM(bidule->ABL) &&
          ((signal = (losig_list *)searchTH(losigHash,VALUE_ATOM(bidule->ABL)))
                 != (losig_list *) VIDETH))
          signal->TYPE = 'E';
       else
       {
	  if (capa && sigAux)
         signal = addlosig(fig,index++,addchain((chain_list *)NULL,(void *)bp->NAME),'E',(float)sigAux->capa/1000);
	  else
            signal = addlosig(fig,index++,addchain((chain_list *)NULL,(void *)bp->NAME),'E',0.0);
       }

      }
      else    /* ce n'est pas une sortie */
      {
	  if (capa && sigAux)
         signal = addlosig(fig,index++,addchain((chain_list *)NULL,(void *)bp->NAME),'E',(float)sigAux->capa/1000);
	  else
            signal = addlosig(fig,index++,addchain((chain_list *)NULL,(void *)bp->NAME),'E',0.0);
      }
      addlocon(fig,bp->NAME,signal,bp->DIRECTION);
      addTH(losigHash,bp->NAME,signal);
   }
   while (bp = bp->NEXT);
   beh->BEPOR = (bepor_list *)reverse((chain_list *)beh->BEPOR);


   if (searchTH(losigHash,namealloc("vdd")) == VIDETH)
   {
      signal = addlosig(fig,index++,addchain((chain_list *)NULL,(void *)namealloc("vdd")),'E',0.0);
      addTH(losigHash,namealloc("vdd"),signal);
      addlocon(fig,namealloc("vdd"),signal,'X');
   }
   if (searchTH(losigHash,namealloc("vss")) == VIDETH)
   {
      signal = addlosig(fig,index++,addchain((chain_list *)NULL,(void *)namealloc("vss")),'E',0.0);
      addTH(losigHash,namealloc("vss"),signal);
      addlocon(fig,namealloc("vss"),signal,'X');
   }

		/* les instances */
   out = beh->BEOUT;
   while (out)
   {
      if (ATOM(out->ABL))		/* cas low ou high */
         cell = (cellList *)testObj(VALUE_ATOM(out->ABL),'c');
      else
         cell = operToCell(out->ABL);
      if (cell)
      {
         ptChain = recupLosig(losigHash,cell,out->NAME,out->ABL);
         if (numberAtomExpr(out->ABL) == 1)
            numberNot++;
         addloins(fig,nameInst(out->NAME),getlofig(cell->nom,'P'),ptChain);
      }
      out = out->NEXT;
   }
   aux = beh->BEAUX;
   while (aux)
   {
      if (ATOM(aux->ABL))
         cell = (cellList *)testObj(VALUE_ATOM(aux->ABL),'c');
      else
         cell = operToCell(aux->ABL);
      if (cell)
      {
         ptChain = recupLosig(losigHash,cell,aux->NAME,aux->ABL);
         if (numberAtomExpr(aux->ABL) == 1)
            numberNot++;
         addloins(fig,nameInst(aux->NAME),getlofig(cell->nom,'P'),ptChain);
      }
       aux = aux->NEXT;
   }

   bus = beh->BEBUS;
   while (bus)
   {
   biabl_list *biabl = bus->BIABL;
   int cpt = 1;

   do
      if (!ATOM(biabl->VALABL))
      {
         cell = operToCell(biabl->VALABL);
         if (cell == NULL)
         {
            printf("genMBKBeh : Error - bad befig : bad operator %s\n",
		   bus->NAME);
            exit(-1);
         }
         ptChain = recupLosig(losigHash,cell,bus->NAME,biabl->VALABL);
         addloins(fig,gensym(nameInst(bus->NAME),cpt++),getlofig(cell->nom,'P'),
			ptChain);
      }
      while (biabl = CDR(biabl));
      bus = bus->NEXT;
   }

   bux = beh->BEBUX;
   while (bux)
   {
   biabl_list *biabl = bux->BIABL;
   int cpt = 1;

   do
      if (!ATOM(biabl->VALABL))
      {
         cell = operToCell(biabl->VALABL);
         if (cell == NULL)
         {
            printf("genMBKBeh : Error - bad befig : bad operator %s\n",
		   bux->NAME);
            exit(-1);
         }
         ptChain = recupLosig(losigHash,cell,bux->NAME,biabl->VALABL);
         addloins(fig,gensym(nameInst(bux->NAME),cpt++),getlofig(cell->nom,'P'),
			ptChain);
      }
      while (biabl = CDR(biabl));
      bux = bux->NEXT;
   }

	/* recherche de l'index max */
   indexMax = 0;
   for(losig = fig->LOSIG; losig; losig = losig->NEXT)
      if (indexMax < losig->INDEX)
         indexMax = losig->INDEX;

   reg = beh->BEREG;
   while (reg)
      {
      biabl_list *biabl = reg->BIABL;

      if (!ATOM(biabl->VALABL))
         {
         lofig_list *figReg;
         chain_list *sign, *newChain = (chain_list *)NULL;
         locon_list *con;
         chain_list *inter = (chain_list *)NULL, *interf;
         Alist *i;

         cell = operToCell(biabl->VALABL);
         if (cell == NULL)
            {
            printf("genMBKBeh : Error - bad befig : bad operator %s\n",
		   reg->NAME);
            exit(-1);
            }
         ptChain = recupLosig(losigHash,cell,reg->NAME,biabl->VALABL);

		/* probleme des ressources a 2 sorties */
         figReg = getlofig(cell->nom,'P');

/*     i = restoredirvbe(figReg); */

         for(cellLo = mappSys->ptcell; cellLo && cellLo->nom != figReg->NAME;
             cellLo = cellLo->NEXT)
            ;
         if (cellLo && ((cellLo->type == 'd') || (cellLo->type == 'r')))
            {
            for(i = cellLo->interface; i; i = i->NEXT)
                inter = addchain(inter, (void *)i->name);

            sign = ptChain;
            con = figReg->LOCON;
            interf = inter;

            while(con)
               {
               if (!interf || (renameSig(con->NAME) != (char *)interf->DATA))
                  {
                  char *bidon = mbkalloc(15);

/*
                  printf("Con %s inexistant \n", con->NAME);
*/
                  indexMax++;
                  sprintf(bidon, "SLBIDON%d", indexMax);
                  sigBidon = addlosig(fig, indexMax,
                                      addchain((chain_list *)NULL,
                                            (void *)bidon), INTERNAL, 0.0);
                  newChain = addchain(newChain, (void *)sigBidon);
                  }
               else
                  {
                  newChain = addchain(newChain, sign->DATA);
                  sign = sign->NEXT;
                  interf = interf->NEXT;
                  }
               con = con->NEXT;
               }
            freechain(ptChain);
            ptChain = reverse(newChain);
            addloins(fig,nameInst(reg->NAME),figReg,ptChain);
            }
         else
            {
            printf("Error MBK generation : %s not found\n\n", cell->nom);
            exit(1);
            }
         }
      reg = reg->NEXT;
      }

   if (erreur)
   {
      printf("Mapping aborted\n");
      exit(1);
   }

	/* Mise a jour des directions des connecteurs */
lofigchain(fig);
if (!restorealldir(fig))
   {
   printf("MBK ERROR : restorealldir failed\n\n");
   exit(1);
   }

if (0)
{
    /* ********************************************************************* */
	/* Post-traitement sur les latchs et bascules a 2 sorties : Q et Q' */

	/* construction de listes des bascules et des latchs */
for(cellLo = mappSys->ptcell; cellLo; cellLo = cellLo->NEXT)
   if (cellLo->type == 'r')
      regCell = addptype(regCell, (long)NULL, (void *)cellLo);
   else
      if (cellLo->type == 'd')
         bdCell = addptype(bdCell, (long)NULL, (void *)cellLo);


	/* recherche des bascules D compatibles */
for(cellMod = bdCell; cellMod; cellMod = cellMod->NEXT)
   for(cellAutre = bdCell; cellAutre; cellAutre = cellAutre->NEXT)
      if (cellMod != cellAutre)
         {
         biabl_list *babl;
         short ok = 1;

         for(b1abl = ((cellList *)cellAutre->DATA)->val_abl, 
             b2abl = ((cellList *)cellMod->DATA)->val_abl;
             b1abl && b2abl; b1abl = b1abl->NEXT, b2abl = b2abl->NEXT)
            {
            if (!equalExpr(b1abl->CNDABL, b2abl->CNDABL))
               ok = 0;
            if (!equalExpr(b1abl->VALABL, b2abl->VALABL))
               ok = 0;
            }
         if (!b1abl && !b2abl && ok)
            {
            cellMod->TYPE = (long)addchain((chain_list *)cellMod->TYPE, (void *)cellAutre->DATA);
         
/*
            printf("  %s et %s compatibles\n", ((cellList *)cellMod->DATA)->nom, ((cellList *)cellAutre->DATA)->nom);
*/
            }
         }

	/* recherche des registres compatibles */
for(cellMod = regCell; cellMod; cellMod = cellMod->NEXT)
   for(cellAutre = regCell; cellAutre; cellAutre = cellAutre->NEXT)
      if (cellMod != cellAutre)
         {
         biabl_list *babl;
         short ok = 1;

         for(b1abl = ((cellList *)cellAutre->DATA)->val_abl, 
             b2abl = ((cellList *)cellMod->DATA)->val_abl;
             b1abl && b2abl; b1abl = b1abl->NEXT, b2abl = b2abl->NEXT)
            {
            if (!equalExpr(b1abl->CNDABL, b2abl->CNDABL))
               ok = 0;
            if (!equalExpr(b1abl->VALABL, b2abl->VALABL))
               ok = 0;
            }
         if (!b1abl && !b2abl && ok)
            {
            cellMod->TYPE = (long)addchain((chain_list *)cellMod->TYPE, (void *)cellAutre->DATA);
            
/*
            printf("  %s et %s compatibles\n", ((cellList *)cellMod->DATA)->nom, ((cellList *)cellAutre->DATA)->nom);
*/
            }
         }

	/* parcours des instances et recherche des ressources */
for(inst = fig->LOINS; inst; inst = inst->NEXT)
   {
   short encore = 1;

   for(cellLo = mappSys->ptcell; cellLo && cellLo->nom != inst->FIGNAME;
       cellLo = cellLo->NEXT);
   if (cellLo && ((cellLo->type == 'd') || (cellLo->type == 'r')))
      {
      ptype_list *liste;
      locon_list *con;
      chain_list *pl;
      short nbOut = 0, nbInv = 0;
      locon_list *outF;
      losig_list *sigNeg = (losig_list *)NULL;

      for(con = inst->LOCON; con; con = con->NEXT)
         if (con->DIRECTION == OUT)
            nbOut++;

      if (nbOut == 2)
         {

         for(con = inst->LOCON; con; con = con->NEXT)
            {
            if (con->DIRECTION == OUT)
               if (strncmp((char *)con->SIG->NAMECHAIN->DATA, (char *)sigBidon->NAMECHAIN->DATA, 7))
                  {
                  liste = getptype(con->SIG->USER, (long)LOFIGCHAIN);
/*
                  printf("Inst %s [%s] a pour modele %s [%s/%s]\n",
                         inst->INSNAME, inst->FIGNAME, cellLo->nomlog, cellLo->nom,
                            con->NAME);
*/
                  for(pl = (chain_list *)liste->DATA; pl; pl = pl->NEXT)
                     {
                     locon_list *conAux = (locon_list *)pl->DATA;
      
                     if (conAux->ROOT != (void *)inst)
                        if (conAux->TYPE == INTERNAL)
                           {
                           loins_list *fanout = (loins_list *)conAux->ROOT;

                           for(cellLo = mappSys->ptcell;
                               cellLo && cellLo->nom != fanout->FIGNAME;
                               cellLo = cellLo->NEXT);
   
/*
                           printf(" -%s (%s/%s)-\n", conAux->NAME, fanout->FIGNAME, cellLo->nomlog);
*/
                           if (cellLo->nomlog == inv)
                              {
                              locon_list *conInv;

                              nbInv++;
                              for(conInv = fanout->LOCON; conInv;
                                  conInv = conInv->NEXT)
                                 if (conInv->DIRECTION == OUT)
                                    sigNeg = conInv->SIG;
                              delloins(fig, fanout->INSNAME);
                              }
                           }
                     }
                  }
               else
                  {
			/* connecteur rattache au signal bidon */
                  outF = con;
                  }
            }
         if (nbInv > 1)
            {
            printf("ERROR : register %s[%s] has more than one inversor\n",
                   inst->INSNAME, inst->FIGNAME);
            exit(1);
            }
         if (sigNeg)
            {
            dellosig(fig, outF->SIG->INDEX);
            outF->SIG = sigNeg;
            }
         }
      else
         if (nbOut == 1)
            {
            ptype_list *cellEqui;
            cellList *equival = (cellList *)NULL;
            loins_list *fanoutInv;

		/* recherche equivalent 2 sorties */
            if (cellLo->type == 'r')
               cellEqui = regCell;
            else
               cellEqui = bdCell;
            while(cellEqui)
               {
               if (((cellList *)cellEqui->DATA == cellLo) && 
                   (cellEqui->TYPE != 0))
                  equival = (cellList *)((chain_list *)cellEqui->TYPE)->DATA;
               cellEqui = cellEqui->NEXT;
               }
            if (equival)
               {
/*
               printf("%s[%s] a comme equivalent %s\n", inst->INSNAME, inst->FIGNAME, equival->nom);
*/
               for(con = inst->LOCON; con; con = con->NEXT)
                  if (con->DIRECTION == OUT)
                     {
                     liste = getptype(con->SIG->USER, (long)LOFIGCHAIN);
                     for(pl = (chain_list *)liste->DATA; pl; pl = pl->NEXT)
                        {
                        locon_list *conAux = (locon_list *)pl->DATA;
      
                        if (conAux->ROOT != (void *)inst)
                           if (conAux->TYPE == INTERNAL)
                              {
                              loins_list *fanout = (loins_list *)conAux->ROOT;

                              for(cellLo = mappSys->ptcell;
                                  cellLo && cellLo->nom != fanout->FIGNAME;
                                  cellLo = cellLo->NEXT);
   
                              if (cellLo->nomlog == inv)
                                 {
                                 locon_list *conInv;

                                 nbInv++;
                                 fanoutInv = fanout;
                                 for(conInv = fanout->LOCON; conInv;
                                    conInv = conInv->NEXT)
                                 if (conInv->DIRECTION == OUT)
                                    sigNeg = conInv->SIG;
                                 }
                              }
                        }
                     }
               if (nbInv == 1)
                  {
                  lofig_list *figEqui = getlofig(equival->nom, 'P');
                  chain_list *lstSig = (chain_list *)NULL, *ctrl;
                  char *oldName = inst->INSNAME;
                  locon_list *conEqui;

                  for(conEqui = figEqui->LOCON; conEqui; conEqui = conEqui->NEXT)
                     {
                     for(con = inst->LOCON; con && con->NAME != conEqui->NAME; con= con->NEXT);
                     if (con)
                        lstSig = addchain(lstSig, (void *)con->SIG);
                     else
                        lstSig = addchain(lstSig, (void *)sigNeg);
                     }
                          
/*
                  printf("Remplacement de %s[%s] par %s[%s]\n",
                         oldName, inst->FIGNAME, inst->INSNAME, figEqui->NAME);
*/
			/* destruction du latch a 1 sortie */
                  delloins(fig, inst->INSNAME);
			/* ajout du latch a 2 sorties */
                  restoredirvbe(figEqui);
                  addloins(fig, oldName, figEqui, reverse(lstSig));
			/* destruction de l'inverseur */
                  delloins(fig, fanoutInv->INSNAME);
                  lofigchain(fig);
                  }
               }
         }
      }
   }
}

	/* detection des portes sans fanout */
lofigchain(fig);
for(inst = fig->LOINS; inst; inst = inst->NEXT)
   {
   locon_list *con;
   short nbOut = 0;

   for(con = inst->LOCON; con; con = con->NEXT)
      if (con->DIRECTION == OUT)
         nbOut++;

   if (nbOut == 1)
      for(con = inst->LOCON; con; con = con->NEXT)
         if (con->DIRECTION == OUT)
            {
            ptype_list *liste = getptype(con->SIG->USER, (long)LOFIGCHAIN);

            if (!((chain_list *)liste->DATA)->NEXT)
               {
               printf("Warning : Gate %s [%s] has nothing connected to connector %s\n",
                      inst->INSNAME, inst->FIGNAME, con->NAME);
               supp = addchain(supp, (void *)inst->INSNAME);
               }
            }
   }
lofigchain(fig);

	/* suppression des portes sans fanout */
for(aSupp = supp; aSupp; aSupp = aSupp->NEXT)
   delloins(fig, (char *)aSupp->DATA);
freechain(supp);

	/* Generation de la netlist sur disque */
printf("MBK Driving '%s/%s.%s'...\n", SL_BEH_LIB, nomFig, SL_OUT_LO);
fflush(stdout);
savelofig(fig);

	/* parcours des modeles : calcul des resultats */
for(mod = fig->MODELCHAIN; mod; mod = mod->NEXT)
   countMod++;
for(inst = fig->LOINS; inst; inst = inst->NEXT)
   {
   totalInst++;
   totalSurf += Surface((char *)inst->FIGNAME);
   }
maxDepthBst(beh, &numberCell, &numberCone);
printf("\n================================  RESULTS  ====================================\n");
printf("Number of cells used             = %d\n",countMod);
printf("Number of gates used             = %d ",totalInst);
printf("(%d inverters)\n",numberNot);
printf("Number of grids                  = %d (%d)\n",totalSurf,totalSurf*252);
printf("Depth maximum (in gates)         = %d ",numberCell);
printf("(%d eq. negative gates)\n",numberCone); 
printf("===============================================================================\n");

dellofig(nomFig);
if (!SL_NAME_LOG) mbkfree(nomFig);
destroyTH(losigHash);
}

chain_list *recupLosig(losigHash,cell,name,abl)
pTH losigHash;
cellList *cell;
char *name;
chain_list *abl;
{
Alist *aux = cell->interface;
chain_list *res = NULL;

if (cell->entrees)
   {
   initAlist(abl,cell->entrees);
   do
      {
      Alist *val = searchAlist(cell->entrees,aux->name);
   
      if (val)
         aux->ptChain = val->ptChain;
      else
         if (memberChain_list(aux->name,cell->sorties))
            aux->ptChain = createAtom(name);
         else
            aux->ptChain = createAtom(aux->name);
      }
   while (aux = CDR(aux));
   }
else
   {
   do
      {
      if (memberChain_list(aux->name,cell->sorties))
         aux->ptChain = createAtom(name);
      else
         aux->ptChain = createAtom(aux->name);
      }
   while (aux = CDR(aux));
   }
aux = cell->interface;
do
   {
   if (searchTH(losigHash,(char *)CAR(aux->ptChain)) == VIDETH)
      {
      printf("Cellule %s : %s --> %s\n",cell->nomlog,name,CAR(aux->ptChain));
      displayAlist(cell->interface);
      exit(-1);
      }
   res = addchain(res,(void *)searchTH(losigHash,(char *)CAR(aux->ptChain)));
   }
while (aux = CDR(aux));
if (cell->entrees)
   resetAlist(cell->entrees,0);
return res;
}
