/****************************************************************************/
/*                                                                          */
/*                      Chaine de CAO & VLSI   Alliance                     */
/*                                                                          */
/*    Produit :  optimiseur de netlist                                      */
/*    Fichier :  no_systemp.c                                               */
/*                                                                          */
/*    (c) copyright 1991 Laboratoire MASI equipe CAO & VLSI                 */
/*    Tous droits reserves                                                  */
/*    Support : e-mail cao-vlsi@masi.ibp.fr                                 */
/*                                                                          */
/*    Auteur(s) :  N. DICTUS                            le : 04/10/1993     */
/*                                                                          */
/*    Modifie par :                                     le : ../../....     */
/*    Modifie par :                                     le : ../../....     */
/*    Modifie par :                                     le : ../../....     */
/*                                                                          */
/****************************************************************************/

#include <stdlib.h>
#include MUT_H
#include MLO_H
#include LOG_H
#include "ctype.h"
#include "../load/types_map.h"
#include "no_type.h"
#include "no_system.h"
#include "enveloppe.h"
#include "../load/no_optim.h"

pTH dejaTraite;

/*----------------------------------------------------------------------------
initializeNOParam : initialise les parametres de Netoptim.
------------------------------------------------------------------------------
retour		: un pointeur sur une structure param.
------------------------------------------------------------------------------*/
param *initializeNOParam(delay,factor,capaPO,capaPI,delayPO,resistPI,delayPI,coupleDelay)
int delay;
int factor;
ptype_list *capaPO;
ptype_list *capaPI;
ptype_list *delayPO;
ptype_list *resistPI;
ptype_list *delayPI;
ptype_list *coupleDelay;
{
param *par = (param *) malloc (sizeof(param));

par->mode = 0;
par->level = 1;
par->numTransN = par->numTransP = 1;
par->maxSlopeTime = factor;
par->intermediate = (chain_list *)NULL;
par->delayPI = delayPI;
par->earlyPO = (chain_list *)delayPO;
par->impedancePI = capaPI;
par->capaPO = capaPO;
return(par);
}

/*----------------------------------------------------------------------------
initializeNOSystem: alloue no_sys *
------------------------------------------------------------------------------
retour		: un pointeur sur une structure systeme. 
------------------------------------------------------------------------------*/
no_system *initializeNOSystem()
{
no_system *no;

no = (no_system *) malloc (sizeof(no_system));

no->name     = (char *) malloc (100);
no->file      = (char *) malloc (100);
no->fileOut      = (char *) malloc (100);
no->filePar   = (char *) malloc (100);
no->fileLog  = (char *) malloc (100);
no->fileParam = (char *) malloc (100);
no->log_lib   = (char *) malloc (100);
no->par_lib   = (char *) malloc (100);
no->cata_lib   = (ptype_list *)NULL;
no->in_lo   = (char *) malloc (10);
no->out_lo   = (char *) malloc (10);
no->version = (char *) malloc(100);

return( no );
}

/*----------------------------------------------------------------------------
majSysCellNeto :
------------------------------------------------------------------------------
retour		: 
------------------------------------------------------------------------------*/
short majSysCellNeto(lofig, trace, option, cataLib, inLo, outLo,
         delayPI, delayPO, capaPI, capaPO, resistPI, coupleDelay, delay, factor)
lofig_list *lofig;
int trace;
char option;
ptype_list *cataLib;
char *inLo, *outLo;
ptype_list *delayPI, *delayPO, *capaPI, *capaPO, *resistPI, *coupleDelay;
int delay, factor;
{
ptype_list *p;

NO_LOG   = lofig;
lofigchain(lofig);
NO_TRACE = trace;
NO_OPTION = option;
NO_CATA_LIB = cataLib;
NO_IN_LO = inLo;
NO_OUT_LO = outLo;

NO_PAR = initializeNOParam(delay,factor,capaPO,capaPI,delayPO,resistPI,delayPI,coupleDelay);

cellInit();
if (cellLoad(lofig->MODELCHAIN) != 0)
   {
   calculEnveloppe(NO_CELLS);
   if (!restorealldir(lofig))
      {
      printf("Adding connector direction failed on %s\n\n", lofig->NAME);
      exit(1);
      }
   addConDirLofig(lofig);

   return 1;
   }
else
   {
   PRINTF("\nERROR : cells library not found in %s\n\n", getenv("MBK_CATA_LIB"));
   return 0;
   }
}

/*----------------------------------------------------------------------------
laxOptimFanout :
------------------------------------------------------------------------------
retour		: 
------------------------------------------------------------------------------*/
lofig_list *laxOptimFanout(lofig, trace, option, cataLib, inLo, outLo,
         delayPI, delayPO, capaPI, capaPO, resistPI, coupleDelay, delay, factor)
lofig_list *lofig;
int trace;
char option;
chain_list *cataLib;
char *inLo, *outLo;
ptype_list *delayPI, *delayPO, *capaPI, *capaPO, *resistPI, *coupleDelay;
int delay, factor;
{
loins_list *inst;
locon_list *con;
ptype_list *p;
int surfaceInit ;

if (majSysCellNeto(lofig, trace, option, cataLib, inLo, outLo, delayPI, delayPO, capaPI, capaPO, resistPI, coupleDelay, delay, factor))
   {
   surfaceInit = statistics(NO_LOG, 0);

   dejaTraite = createTH(500);
   optimFanMax();
   printf("\n");

	/* optimisation des entrees primaires */

/* A revoir avec LAX
   if (NO_CAPAPI)
      {
      for(p = NO_CAPAPI; p ; p = p->NEXT)
         {
         optimEntrees((char *)p->DATA, p->TYPE);
         addTH(dejaTraite, (char *)p->DATA, 1);
         }
      }
*/
   for(con = NO_LOG->LOCON; con; con = con->NEXT)
      if ((con->DIRECTION == IN) && !isvdd(con->NAME) && !isvss(con->NAME))
         if (searchTH(dejaTraite, con->NAME) == EMPTYTH)
            optimEntrees(con->NAME, 4*capaNot());
   
   destroyTH(dejaTraite);
   capaEntrees();
   clearmodel(lofig);

   statistics(lofig, surfaceInit);
   }

return lofig;
}

/*----------------------------------------------------------------------------
laxAssignFanin :
------------------------------------------------------------------------------
retour		: 
------------------------------------------------------------------------------*/
lofig_list *laxAssignFanin(lofig, trace, option, cataLib, inLo, outLo,
         delayPI, delayPO, capaPI, capaPO, resistPI, coupleDelay, delay, factor)
lofig_list *lofig;
int trace;
char option;
chain_list *cataLib;
char *inLo, *outLo;
ptype_list *delayPI, *delayPO, *capaPI, *capaPO, *resistPI, *coupleDelay;
int delay, factor;
{
loins_list *inst;

if (majSysCellNeto(lofig, trace, option, cataLib, inLo, outLo, delayPI, delayPO, capaPI, capaPO, resistPI, coupleDelay, delay, factor))
   {
   calcul_delai(lofig, 0);

	/* assignation de fanin */
   assignTH = createTH(1000);

   for(inst = lofig->LOINS; inst; inst = inst->NEXT)
      assignFaninEx(inst, 1);

   destroyTH(assignTH);

   calcul_delai(lofig, 0);
   }
return lofig;
}

/*----------------------------------------------------------------------------
laxCalcul_delai :
------------------------------------------------------------------------------
retour		: 
------------------------------------------------------------------------------*/
lofig_list *laxCalcul_delai(lofig, trace, option, cataLib, inLo, outLo,
         delayPI, delayPO, capaPI, capaPO, resistPI, coupleDelay, delay, factor)
lofig_list *lofig;
int trace;
char option;
chain_list *cataLib;
char *inLo, *outLo;
ptype_list *delayPI, *delayPO, *capaPI, *capaPO, *resistPI, *coupleDelay;
int delay, factor;
{
if (majSysCellNeto(lofig, trace, option, cataLib, inLo, outLo, delayPI, delayPO, capaPI, capaPO, resistPI, coupleDelay, delay, factor))
   {
   ptype_list *p;

printf("Affichage NO_DELAYPI\n");
for(p = NO_DELAYPI; p; p = p->NEXT)
   printf("IN %s = %d\n", (char *)p->DATA, p->TYPE);
   calcul_delai(lofig, 1);
   }

return lofig;
}

/*----------------------------------------------------------------------------
laxDisplayFanout :
------------------------------------------------------------------------------
retour		: 
------------------------------------------------------------------------------*/
lofig_list *laxDisplayFanout(lofig, trace, option, cataLib, inLo, outLo,
         delayPI, delayPO, capaPI, capaPO, resistPI, coupleDelay, delay, factor)
lofig_list *lofig;
int trace;
char option;
chain_list *cataLib;
char *inLo, *outLo;
ptype_list *delayPI, *delayPO, *capaPI, *capaPO, *resistPI, *coupleDelay;
int delay, factor;
{
if (majSysCellNeto(lofig, trace, option, cataLib, inLo, outLo, delayPI, delayPO, capaPI, capaPO, resistPI, coupleDelay, delay, factor))
   {
   displayLofig(lofig, 3);
   }
}
