/****************************************************************************/
/*                                                                          */
/*                      Chaine de CAO & VLSI   Alliance                     */
/*                                                                          */
/*    Produit :  Synthetiseur Logique                                       */
/*    Fichier :  fp_system.c                                                */
/*                                                                          */
/*    (c) copyright 1991 Laboratoire MASI equipe CAO & VLSI                 */
/*    Tous droits reserves                                                  */
/*    Support : e-mail cao-vlsi@masi.ibp.fr                                 */
/*                                                                          */
/*    Auteur(s) :  L. Burgun                            le : 16/07/1991     */
/*                                                                          */
/*    Modifie par :                                     le : 25/10/1991     */
/*    Modifie par :                                     le : ../../....     */
/*    Modifie par :                                     le : ../../....     */
/*                                                                          */
/****************************************************************************/

#include MUT_H
#include LOG_H
#include BEH_H
#include "ctype.h"
#include "../ablorder/sl_order.h"
#include "../compil/lax_param.h"
#include "fp_type.h"

char *getenv();

/*----------------------------------------------------------------------------
verifFamily	: verifie le type de la famille 
------------------------------------------------------------------------------
retour		: un entier a 1 si OK, 0 sinon.
------------------------------------------------------------------------------*/
int verifFamily(argv,place)
char *argv[];
int place;
{
if (!strcmp(argv[place],"-target=X3000") ||
    !strcmp(argv[place],"-target=X4000") ||
    !strcmp(argv[place],"-target=NODE") ||
    !strcmp(argv[place],"-target=ACT1") ||
    !strcmp(argv[place],"-target=ACT2"))
   return(1);
else
   return(0);
}

/*----------------------------------------------------------------------------
verifArgsFPGA	: verifie les arguments de la ligne de commande.
------------------------------------------------------------------------------
retour		: un entier a 1 si OK, 0 sinon.
------------------------------------------------------------------------------*/

int verifArgsFPGA(fp,argc,argv)
fp_system *fp;
int argc;
char *argv[];
{
FILE *fic;
FILE *fopen();
char *carint;

		/* version interactive */

if (argc == 2)
   {
   argv[1] = (char *) genNAME("%s.vbe",argv[1]);
   return(1);
   }

if (argc > 1 && argv[1][0] == '-') 
   {
   if (strcmp(argv[1],"-o") && strcmp(argv[1],"-l"))
      {
      printf("\nfpga 1.01      : bad option '%s'\n\n",argv[1]) ;
      return(0) ;
      }
   }

		/* avec un fichier de parametres */

if (argc == 3 && strcmp(argv[1],"-o") &&  strcmp(argv[1],"-l"))
   {
   argv[1] = (char *) genNAME("%s.vbe",argv[1]);
   argv[2] = (char *) genNAME("%s.lax",argv[2]);

	/* on verifie l'existence du fichier de parametres */

   if (!strcmp(fp->par_lib,"."))
      {
      if(!(fic = fopen(argv[2],"r")))
      	{
	printf("\nfpga 1.01      : unable to open '%s'\n\n",argv[2]) ;
	return(0) ;
	}
      else
        fclose(fic);
      }
   else
      {
      
      carint = (char *) genNAME("%s/%s",fp->par_lib,argv[2]);
      if(!(fic = fopen(carint,"r")))
      	{
	printf("\nfpga 1.01      : unable to open ") ;
        printf(" '%s'\n\n",carint);
        mbkfree(carint);
	return(0) ;
	}
      else
        fclose(fic);
      mbkfree(carint);
      }
   return(1);
   }			/* fin appel version interactive */

if (argc < 4 || argc > 5)
   {
   printf("\nfpga 1.01 \nusage  :  fpga -option -target=family <file_entity> <file_par>\n");
   printf("option : -o   global optimization\n");
   printf("         -l   local optimization\n"); 
   printf("family : X3000 Xilinx 3090\n");
   printf("         X4000 Xilinx 4090\n");
   printf("         ACT1  Actel 1\n");
   printf("         ACT2  Actel 2\n");
   return(0) ;
   }


if (!verifFamily(argv,2))
   return(0);

argv[3] = (char *) genNAME("%s.vbe",argv[3]);
if (!strcmp(fp->beh_lib,"."))
   {
   if(!(fic = fopen(argv[3],"r")))
	{
	printf("\nfpga 1.01      : unable to open '%s'\n\n",argv[3]) ;
	return(0) ;
	}
   else
        fclose(fic);
   }
else
   {
   if(!(fic = fopen(carint = (char *) genNAME("%s/%s",fp->beh_lib,argv[3]),"r")))
	{
	printf("\nfpga 1.01      : unable to open '%s'\n\n",carint) ;
        mbkfree(carint);
	return(0) ;
	}
   else
        fclose(fic);
   mbkfree(carint);
   }

		/* avec un fichier de parametre */

if (argc == 5)
   {
   argv[4] = (char *) genNAME("%s.lax",argv[4]);
   if (!strcmp(fp->par_lib,"."))
      {
      if(!(fic = fopen(argv[4],"r")))
      	{
	printf("\nfpga 1.01      : unable to open '%s'\n\n",argv[4]) ;
	return(0) ;
	}
      else
        fclose(fic);
      }
   else
      {
      if(!(fic = fopen(carint = (char *) genNAME("%s/%s",fp->par_lib,argv[4]),"r")))
      	{
	printf("\nfpga 1.01      : unable to open ") ;
        printf(" '%s'\n\n",genNAME("%s",carint));
	return(0) ;
	}
      else
        fclose(fic);
      mbkfree(carint);
      }
   }

return(1);
}


/*----------------------------------------------------------------------------
fpMajSystem: mets a jour les champs du systeme 
------------------------------------------------------------------------------
retour		: rien 
-----------------------------------------------------------------------------*/
void fpMajSystem(fp)
fp_system *fp;
{
if (!getenv("MBK_WORK_LIB"))
   strcpy(fp->beh_lib,".");
else
   strcpy(fp->beh_lib,getenv("MBK_WORK_LIB"));

if (!existDirectory(fp->beh_lib))
   {
   printf("\nfpga 1.01      : MBK_WORK_LIB -> the directory '%s' doesn't exist\n",fp->beh_lib);
   exit(-1);
   }

if (!getenv("MBK_PAR_LIB"))
   strcpy(fp->par_lib,".");
else
   strcpy(fp->par_lib,getenv("MBK_PAR_LIB"));

if (!existDirectory(fp->par_lib))
   {
   printf("\nfpga 1.01      : MBK_PAR_LIB -> the directory '%s' doesn't exist\n",fp->par_lib);
   exit(-1);
   }

if (getenv("MBK_TRACE") == NULL || !strcmp(getenv("MBK_TRACE"),"0"))
   fp->trace = 0; 
else
   if (!strcmp(getenv("MBK_TRACE"),"1"))
      fp->trace = 1;
   else
      if (!strcmp(getenv("MBK_TRACE"),"2"))
         fp->trace = 2;
      else
         if (!strcmp(getenv("MBK_TRACE"),"3"))
            fp->trace = 3;
         else
            fp->trace = 0;

		/* RULES_DC */ 

if (getenv("MBK_NODC") == NULL || !strcmp(getenv("MBK_NODC"),"0"))
   fp->dc = 1;	
else
   fp->dc = 0;

		/* affichage de la banniere */

if (getenv("MBK_BANN"))
   fp->banniere = 0;	
else
   fp->banniere = 1;

		/* meme nom de lofig que de befig */ 

if (!getenv("MBK_NAME_LOG"))
   fp->name_log = 0;		/* on genere une lofig du nom  + optim */
else
   fp->name_log = 1;		/* on genere une lofig du meme nom */

/* appel aux fonctions d'ordonnancement - 0 rien - 1 ABL - 2 ABL + BDD */ 

if (!getenv("MBK_ORDER"))
   fp->makeOrder = 2;
else
   if (!strcmp(getenv("MBK_ORDER"),"0"))
      fp->makeOrder = 0;	
   else
      if (!strcmp(getenv("MBK_ORDER"),"1"))
         fp->makeOrder = 1;
      else
         fp->makeOrder = 2;

if (fp->makeOrder >= 1)
   fp->order = 1;

}
/*----------------------------------------------------------------------------
fpAddInfoSystem	: ajoute les infos de process et de fichiers a traiter
------------------------------------------------------------------------------
retour		: rien. 
------------------------------------------------------------------------------*/

void fpAddInfoSystem(fp,mode,argc,argv,version)
fp_system *fp;
int mode;
int argc;
char *argv[];
char *version;
{
char *carint;

strcpy(fp->version,version);
fp->mode = mode;

		/* mode batch */

if (fp->mode == 1)
   {
   strcpy(fp->file,argv[3]) ;
   if (!strcmp(fp->beh_lib,"."))
      strcpy(fp->fileVhdl,argv[3]) ;
   else
      {
      strcpy(fp->fileVhdl,carint = (char *) genNAME("%s/%s",fp->beh_lib,argv[3]));
      mbkfree(carint);
      }
   fp->par = initializeFPParam(2,0,2,NULL,NULL,NULL);

			/* fichier de parametre */

   if (argc == 5)
      {
      strcpy(fp->filePar,argv[4]) ;
      if (!strcmp(fp->par_lib,"."))
         strcpy(fp->fileParam,argv[4]) ;
      else
         {
         strcpy(fp->fileParam,carint = (char *) genNAME("%s/%s",fp->par_lib,argv[4])) ;
         mbkfree(carint);
         }
      fp->par = loadParam(fp->fileParam);
      if (fp->par == NULL) 
 	 { 
	 printf("loadParam : error: bad parameters file \n");
	 exit( -1 );
	 }
      }
   else
      {
      if (!strcmp(fp->par_lib,"."))
         strcpy(fp->fileParam,"default.lax");
      else
         {
         strcpy(fp->fileParam,carint = (char *) genNAME("%s/default.lax",fp->par_lib));
         mbkfree(carint);
         }
      }
   fp->option = *(argv[1]+1);

   if (!strcmp(argv[2],"-target=X3000"))
      fp->family = X3000;
   if (!strcmp(argv[2],"-target=X4000"))
      fp->family = X4000;
   if (!strcmp(argv[2],"-target=ACT1"))
      fp->family = ACT1;
   if (!strcmp(argv[2],"-target=ACT2"))
      fp->family = ACT2;
   if (!strcmp(argv[2],"-target=NODE"))
      fp->family = XNODE;
   }
else		/* mode 0 ou 2 */
   {
   strcpy(fp->file,argv[1]) ;
   if (!strcmp(fp->beh_lib,"."))
      strcpy(fp->fileVhdl,argv[1]) ;
   else
      {
      strcpy(fp->fileVhdl,carint = (char *) genNAME("%s/%s",fp->beh_lib,argv[1]));
      mbkfree(carint);
      }
   fp->par = initializeFPParam(2,0,2,NULL,NULL,NULL);
   if (fp->mode == 0)
      {
      strcpy(fp->filePar,"default.lax");
      if (!strcmp(fp->par_lib,"."))
         strcpy(fp->fileParam,"default.lax");
      else
         {
         strcpy(fp->fileParam,carint = (char *) genNAME("%s/default.lax",fp->par_lib));
         mbkfree(carint);
         }
      }
   else		/* mode 2 */
      {
      strcpy(fp->filePar,argv[2]) ;
      if (!strcmp(fp->par_lib,"."))
         strcpy(fp->fileParam,argv[2]) ;
      else
         {
         strcpy(fp->fileParam,carint = (char *) genNAME("%s/%s",fp->par_lib,argv[2])) ;
         mbkfree(carint);
         }
      fp->par = loadParam(fp->fileParam);
      if (fp->par == NULL) 
 	 { 
	 printf("loadParam : error: bad parameters file \n");
	 exit( -1 );
 	 }
      }
   fp->option = '\0';
   }

mbkenv();
}

/*----------------------------------------------------------------------------
displayFpgaSystem   : affiche les arguments de la synthese 
------------------------------------------------------------------------------
retour		: void 
------------------------------------------------------------------------------*/

void displayFpgaSystem(sys)
fp_system *sys;
{
        /* nouvelle banniere (Septembre 93)*/

alliancebanner("Fpga", FP_VERSION, "FPGA Synthesis", "90-93", ALLIANCE_VERSION);

if (FP_MODE == 1)		/* mode batch */
   {
   printf("================================  Environnement  ==============================\n");
   printf("MBK_WORK_LIB       = %s\n",FP_BEH_LIB);
   printf("MBK_PAR_LIB         = %s\n",FP_PAR_LIB);
   printf("MBK_TRACE           = %d\n",FP_TRACE);
   printf("=======================  Files, Options and Parameters  =======================\n");
   printf("VHDL file          = %s\n",FP_VHDL);
   printf("Parameters file    = %s\n",FP_PARAM);
   printf("Mode               = ");
   switch (FP_OPTION)
       {
       case 'o' : printf("Global optimization\n"); break;
       case 'l' : printf("Local optimization\n"); break;
       }
   printf("RULES_DC           = %d\n",RULES_DC);
   printf("Family             = ");
   switch (FP_FAMILY)
       {
       case X3000 : printf("Xilinx X3000\n"); break;
       case X4000 : printf("Xilinx X4000\n"); break;
       case XNODE : printf("Node BDD\n"); break;
       case ACT1 : printf("Actel ACT1\n"); break;
       case ACT2 : printf("Actel ACT2\n"); break;
       }
   printf("Optimization mode  = %d\n",FP_OPTIM);
   printf("Optimization level = %d\n",FP_LEVEL);
   printf("===============================================================================\n");
   printf("\n");
   }
}


/*----------------------------------------------------------------------------
initializeFPSystem:  alloue sys 
------------------------------------------------------------------------------
retour		: un pointeur sur une structure systeme. 
------------------------------------------------------------------------------*/

fp_system *initializeFPSystem()
{
fp_system *fp;

fp = (fp_system *) malloc (sizeof(fp_system));

fp->orderPI = NULL;

fp->order = 0;
fp->version = (char *) malloc (100);
fp->fileVhdl  = (char *) malloc (100);
fp->file      = (char *) malloc (100);
fp->fileParam = (char *) malloc (100);
fp->filePar   = (char *) malloc (100);

fp->beh_lib   = (char *) malloc (100);
fp->par_lib   = (char *) malloc (100);

return( fp );
}

/*----------------------------------------------------------------------------
initializeFPParam : initialise les parametres de la synthese.
------------------------------------------------------------------------------
retour          : un pointeur sur une structure param.
------------------------------------------------------------------------------*/
 
param *initializeFPParam(optim,aux,level,delayPI,intermediate,optimPO)
int optim;
int aux;
int level;
ptype_list *delayPI;
chain_list *intermediate;
chain_list *optimPO;
{
param *par;
 
par = (param *) malloc (sizeof(param));
par->mode = optim;
par->aux = aux;
par->level = level;
par->delayPI = delayPI;
par->intermediate = intermediate;
par->earlyPO = optimPO;
par->numTransN = 4;
par->numTransP = 4;
 
par->maxSlopeTime = 0;
par->impedancePI = NULL;
par->capaPO = NULL;
par->capaPI = NULL;
 
return(par);
}
