/****************************************************************************/
/*                                                                          */
/*                      Chaine de CAO & VLSI   Alliance                     */
/*                                                                          */
/*    Produit :  Synthetiseur de FSM                                       */
/*    Fichier :  syf_a2beh.c                                                  */
/*                                                                          */
/*    (c) copyright 1992 Laboratoire MASI equipe CAO & VLSI                 */
/*    Tous droits reserves                                                  */
/*    Support : e-mail cao-vlsi@masi.ibp.fr                                 */
/*                                                                          */
/*    Auteur(s) :  C. Sarwary                            le : 28/01/1992     */
/*                                                                          */
/*    Modifie par :                                     le : ../../....     */
/*    Modifie par :                                     le : ../../....     */
/*    Modifie par :                                     le : ../../....     */
/*                                                                          */
/***************************************************************************/
#include<stdio.h>
#include<math.h>
#include<fcntl.h>
#include MUT_H
#include LOG_H
#include"../beh104/beh104.h"
#include "syf_auto.h"
#include "syf_must.h"
#include "syf_beh2fsm.h"
#include "../util/util.h"
#include "../dc/dc.h"
extern int syf_scan ;
/*------------------------------------------------------------------------------
auto2Beh		: Genere une structure de donnees befig a partir d'une
			  structure automate . 
--------------------------------------------------------------
parametres		: pointeur sur le circuit qui va etre pointee par le champ
				  CIRCUI de "beh" => a ne pas detruire par la suite.
--------------------------------------------------------------
return			: befig .
------------------------------------------------------------------------------*/
struct syf_befig *auto2beh(pC)
pCircuit pC ;
{
struct syf_befig *beh ;
struct syf_bepor *por;
struct syf_berin *bein;
biabl_list *biabl ;
pOut  out ;
pReg reg ;
syf_beaux_list *aux ;
syf_bereg_list *behReg ;
syf_beout_list *behOut ;
pTrans trans ;
chain_list *abl ;
char **input ;
char *name;
int i,j,numReg,stackNumBit, numRegOut, numSt ;

beh = syf_beh_addbefig(NULL,autoSys->name) ;
if(autoSys->typeReg == REG_D)
	{
	numReg = autoSys->numberReg ;
	numRegOut = autoSys->numberOut ;
	stackNumBit = autoSys->stackNumBit ;
	numSt = autoSys->numberReg * autoSys->sizeStack ;
	}
else
	{
	numReg = 2 * autoSys->numberReg ;
	numRegOut = 2 * (autoSys->numberOut) ;
	stackNumBit = 2 * autoSys->stackNumBit ;
	numSt = 2 * autoSys->numberReg * autoSys->sizeStack ;
	}

			/* interface */

por = NULL;
bein = NULL ;

/******************** ATTENTION *******************/
/*on remplit l'interface de beh dans l'ordre inverse car un precedent 
		inversement*/

input = autoSys->input + autoSys->numberIn -1 ;
for(i = 0; i < autoSys->numberIn; i++)
  {
  por = syf_beh_addbepor(por,*input,'I','B',0);
  input--;
  }

out = autoSys->out + autoSys->numberOut -1;
for(i = 0; i < autoSys->numberOut; i++)
  {
  if(existName(autoSys->input,autoSys->numberIn,out->name))/* bidirectionnel */
	{
	por = syf_beh_rmvbepor(por,out->name) ;
	por =  syf_beh_addbepor(por,out->name,'B','B',0);
	}
  else
  	por = syf_beh_addbepor(por,out->name,'O','B',0);
  out--;
  }

beh->BEPOR = por; 


input = autoSys->input + autoSys->numberIn -1 ;
for(i = 0; i < autoSys->numberIn; i++)
  {
  bein = syf_beh_addberin(bein,*input,'I','B',0);
  input--;
  }

reg = autoSys->reg ;
for(i = 0; i <  numReg; i++)
   {
   bein = syf_beh_addberin(bein,reg->name,'I','B',0) ;
   reg++ ;
   }
reg = autoSys->regOut ;
for(i = 0; i <  numRegOut; i++)
   {
   if(reg->name != NULL)/* test important pour -scan -pseudorom */
   		bein = syf_beh_addberin(bein,reg->name,'I','B',0) ;
   reg++ ;
   }
if(flagPile && autoSys->stackNumBit != 0)
	{
	reg = autoSys->inStack[0];
 	for(i = 0; i < numSt ; i++)
		{
   		if(reg->abl != NULL)
  			bein = syf_beh_addberin(bein,reg->name,'I','B',0) ;
  		reg++ ;
  		}
	}
 beh->BERIN = bein; 

	/* signaux auxiliaires "codage" et "transition" */

name = nameSl((autoSys->state)->name);
aux = syf_beh_addbeaux(NULL,name,copyExpr(autoSys->code->abl),NULL,'\0');
name = nameMa((autoSys->state)->name);
aux = syf_beh_addbeaux(aux,name,copyExpr(autoSys->state->abl),NULL,'\0');
for(i = 1; i < autoSys->numberState; i++)
   {
   name=nameSl((autoSys->state + i)->name);
   aux=syf_beh_addbeaux(aux,name, copyExpr((autoSys->code + i)->abl),NULL,'\0');
   name=nameMa((autoSys->state + i)->name);
   aux=syf_beh_addbeaux(aux,name, copyExpr((autoSys->state + i)->abl),NULL,'\0');
  }
if(flagPile)
{
  for(i = 0; i < NUMBERCTRL; i++)
	{
	/*printf("ctrlName : %s\n",((autoSys->inCtrl)+i)->name) ;
	displayExpr(((autoSys->inCtrl) + i)->abl) ;*/
     aux=syf_beh_addbeaux(aux,((autoSys->inCtrl) + i)->name,
  			copyExpr(((autoSys->inCtrl) + i)->abl),NULL,'\0');
	}
 /*if(autoSys->typeReg == REG_D) ancien genStack */
  for(i = 0; i < autoSys->numberReg; i++)
	{
	if((autoSys->inFixStack + i)->abl != NULL)
		{
     	aux=syf_beh_addbeaux(aux,(autoSys->inFixStack + i)->name,
  							copyExpr((autoSys->inFixStack + i)->abl),NULL,'\0');
		}
	}
 /*else
  for(i = 0; i < autoSys->numberReg -autoSys->stackNumBit; i++)
	{
     aux=syf_beh_addbeaux(aux,(autoSys->inFixStack + i)->name,
  			copyExpr((autoSys->inFixStack + i)->abl),NULL,'\0');
	} ancien genStack */
}
beh->BEAUX = aux ;


	/* signaux registres : "y"*/

reg = autoSys->reg ;
behReg = NULL ;
for(i = 0; i <  numReg; i++)
   {
   biabl = (biabl_list *) mbkalloc(sizeof(struct biabl)) ;

   biabl->CNDABL = copyExpr(reg->cnd) ;
   biabl->VALABL = copyExpr(reg->abl) ; 
   biabl->NEXT = NULL ;
   behReg = syf_beh_addbereg(behReg,reg->name,biabl,NULL) ;
   reg++ ;
   }
/******** Generation de registres de sorties ************/

reg = autoSys->regOut ;
for(i = 0; i <  numRegOut; i++)
   {
   if(reg->name != NULL && reg->abl != NULL)
		{
   		biabl = (biabl_list *) mbkalloc(sizeof(struct biabl)) ;

   		biabl->CNDABL = copyExpr(reg->cnd) ;
   		biabl->VALABL = copyExpr(reg->abl) ; 
   		biabl->NEXT = NULL ;
   		behReg = syf_beh_addbereg(behReg,reg->name,biabl,NULL) ;
		}
   	reg++ ;
   }

/***** Generation de stack *****/
if(flagPile)
{
/* pour genStackD if(autoSys->typeReg == REG_D)
 {*/
 reg = autoSys->inStack[0];
 if(*(autoSys->inStack + 0) != NULL)
 for(i = 0; i < numSt ; i++)
   {
   if(reg->abl != NULL)
	{
   	biabl = (biabl_list *) mbkalloc(sizeof(struct biabl)) ;

   	biabl->CNDABL = copyExpr(reg->cnd) ;
  	biabl->VALABL = copyExpr(reg->abl) ; 
    biabl->NEXT = NULL ;
    behReg = syf_beh_addbereg(behReg,reg->name,biabl,NULL,0) ;
    }
   reg++ ;
   }

/* ancien genStack 
 }

else
for(j= 0;j< autoSys->sizeStack;j++)
 {
 reg = autoSys->inStack[j];
 for(i = 0; i < stackNumBit ; i++)
   {
   biabl = (biabl_list *) mbkalloc(sizeof(struct biabl)) ;

   biabl->CNDABL = copyExpr(reg->cnd) ;
   biabl->VALABL = copyExpr(reg->abl) ; 
   biabl->NEXT = NULL ;
   behReg = syf_beh_addbereg(behReg,reg->name,biabl,NULL,0) ;
   reg++ ;
   }
 }
*/
}
beh->BEREG = behReg ;

	/* les signaux output */

out = autoSys->out ;
behOut = NULL ;
for(i = 0; i < autoSys->numberOut; i++)
   {
   if(out->name != NULL && out->abl != NULL)
   		behOut = syf_beh_addbeout(behOut,out->name,copyExpr(out->abl),NULL,0) ;
   out++ ;
   }
/*if(syf_scan)
	{
	behOut = syf_beh_addbeout(behOut,autoSys->scout,createAtom((autoSys->reg + 
			numReg - 1)->name),NULL,0) ;
	}
	*/
beh->BEOUT = behOut ;

beh->CIRCUI = pC ;
/*
beh->CIRCUI = createCir() ;
syf_makeBddBeh(beh,beh->CIRCUI,1,syf_trace,9) ;
*/
return(beh) ;

}
/*------------------------------------------------------------------------------
createCir		: genere une structure CIRCUIT .
--------------------------------------------------------------
parametres		: rien .
--------------------------------------------------------------
return			: pCircuit .
------------------------------------------------------------------------------*/
pCircuit createCir()
{
int i ;
pCircuit pC;
char **name ;
 
 /*initializeBdd(2) ;*/
pC = initializeCct("aut",autoSys->numberIn+ 2*autoSys->numberReg,
			autoSys->numberOut) ;
name = autoSys->input ;
while(*name)
        {
        addInputCct(pC,*name) ;
        name++ ;
        }
for(i = 0; i < (autoSys->numberReg); i++)
        addInputCct(pC,nameI(NEXT_STATE,i)) ;
/*for(i = (autoSys->numberReg) - 1; i >= 0; i--)*/
for(i = 0; i < (autoSys->numberReg); i++)
        addInputCct(pC,nameI(CURENT_STATE,i)) ;

return(pC) ;
}
/*------------------------------------------------------------------------------
existName		: verifie si dans la table des noms il existe 'name' .
--------------------------------------------------------------
parametres		: table des noms, nombre de name dans la table, name .
--------------------------------------------------------------
return			: 1 : si oui, 0 : sinon .
------------------------------------------------------------------------------*/
existName(tabName,num,name)
char **tabName ;
int num ;
char *name;
{
int i ;

for(i = 0; i < num; i++)
	if(!strcmp(*(tabName + i),name))
		return(1) ;

return(0) ;
}
/*------------------------------------------------------------------------------
a2BehRom	: Genere une structure de donnees befig a partir d'une
			  structure automate, pour la version ROM . 
--------------------------------------------------------------
parametres		: pointeur sur le circuit qui va etre pointee par le champ
				  CIRCUI de "beh" => a ne pas detruire par la suite.
--------------------------------------------------------------
return			: befig .
------------------------------------------------------------------------------*/
struct syf_befig *a2behRom(pC)
pCircuit pC ;
{
struct syf_befig *beh ;
struct syf_bepor *por;
struct syf_berin *bein;
biabl_list *biabl ;
pOut  out ;
pReg reg ;
syf_beaux_list *aux ;
syf_bereg_list *behReg ;
syf_beout_list *behOut ;
pTrans trans ;
chain_list *abl ;
char **input ;
char *name, *nameVector() ;
int i,j,numReg,stackNumBit, numRegOut, numSt ;

beh = syf_beh_addbefig(NULL,autoSys->name) ;
if(autoSys->typeReg == REG_D)
	{
	numReg = autoSys->numberReg ;
	numRegOut = autoSys->numberOut ;
	stackNumBit = autoSys->stackNumBit ;
	numSt = autoSys->numberReg * autoSys->sizeStack ;
	}
else
	{
	numReg = 2 * autoSys->numberReg ;
	numRegOut = 2 * (autoSys->numberOut) ;
	stackNumBit = 2 * autoSys->stackNumBit ;
	numSt = 2 * autoSys->numberReg * autoSys->sizeStack ;
	}

			/* interface */

por = NULL;
bein = NULL ;

/******************** ATTENTION *******************/
/*on remplit l'interface de beh dans l'ordre inverse car un precedent 
		inversement*/

input = autoSys->input + autoSys->numberIn -1 ;
for(i = 0; i < autoSys->numberIn; i++)
  {
  if(existOut(*input) != -1)/* bidirectionnel */
  	por = syf_beh_addbepor(por,*input,'B','B',0);
  else
  	por = syf_beh_addbepor(por,*input,'I','B',0);
  input--;
  }

for(i = NUMBER_BIT(autoSys->numberState) -1; i >= 0 ; i--)
	por =  syf_beh_addbepor(por,nameVector("adr",i),'O','B',0);

beh->BEPOR = por; 


input = autoSys->input + autoSys->numberIn -1 ;
for(i = 0; i < autoSys->numberIn; i++)
  {
  if(existOut(*input) != -1)/* bidirectionnel */
  	bein = syf_beh_addberin(bein,*input,'B','B',0);
  else
  	bein = syf_beh_addberin(bein,*input,'I','B',0);
  input--;
  }

reg = autoSys->reg ;
for(i = 0; i <  numReg; i++)
   {
   bein = syf_beh_addberin(bein,reg->name,'I','B',0) ;
   reg++ ;
   }
if(flagPile && autoSys->stackNumBit != 0)
	{
	reg = autoSys->inStack[0];
 	for(i = 0; i < numSt ; i++)
		{
   		if(reg->abl != NULL)
  			bein = syf_beh_addberin(bein,reg->name,'I','B',0) ;
  		reg++ ;
  		}
	}
 beh->BERIN = bein; 

	/* signaux auxiliaires "codage" et "transition" */

name = nameSl((autoSys->state)->name);
aux = syf_beh_addbeaux(NULL,name,copyExpr(autoSys->code->abl),NULL,'\0');
name = nameMa((autoSys->state)->name);
aux = syf_beh_addbeaux(aux,name,copyExpr(autoSys->state->abl),NULL,'\0');
for(i = 1; i < autoSys->numberState; i++)
   {
   name=nameSl((autoSys->state + i)->name);
   aux=syf_beh_addbeaux(aux,name, copyExpr((autoSys->code + i)->abl),NULL,'\0');
   name=nameMa((autoSys->state + i)->name);
   aux=syf_beh_addbeaux(aux,name, copyExpr((autoSys->state + i)->abl),NULL,'\0');
  }
if(flagPile)
{
  for(i = 0; i < NUMBERCTRL; i++)
	{
	/*printf("ctrlName : %s\n",((autoSys->inCtrl)+i)->name) ;
	displayExpr(((autoSys->inCtrl) + i)->abl) ;*/
     aux=syf_beh_addbeaux(aux,((autoSys->inCtrl) + i)->name,
  			copyExpr(((autoSys->inCtrl) + i)->abl),NULL,'\0');
	}
 /*if(autoSys->typeReg == REG_D) ancien genStack */
  for(i = 0; i < autoSys->numberReg; i++)
	{
	if((autoSys->inFixStack + i)->abl != NULL)
		{
     	aux=syf_beh_addbeaux(aux,(autoSys->inFixStack + i)->name,
  							copyExpr((autoSys->inFixStack + i)->abl),NULL,'\0');
		}
	}
 /*else
  for(i = 0; i < autoSys->numberReg -autoSys->stackNumBit; i++)
	{
     aux=syf_beh_addbeaux(aux,(autoSys->inFixStack + i)->name,
  			copyExpr((autoSys->inFixStack + i)->abl),NULL,'\0');
	} ancien genStack */
}
beh->BEAUX = aux ;


	/* signaux registres : "y"*/

reg = autoSys->reg ;
behReg = NULL ;
for(i = 0; i <  numReg; i++)
   {
   biabl = (biabl_list *) mbkalloc(sizeof(struct biabl)) ;

   biabl->CNDABL = copyExpr(reg->cnd) ;
   biabl->VALABL = copyExpr(reg->abl) ; 
   biabl->NEXT = NULL ;
   behReg = syf_beh_addbereg(behReg,reg->name,biabl,NULL) ;
   reg++ ;
   }

/***** Generation de stack *****/
if(flagPile)
{
/* pour genStackD if(autoSys->typeReg == REG_D)
 {*/
 reg = autoSys->inStack[0];
 if(*(autoSys->inStack + 0) != NULL)
 for(i = 0; i < numSt ; i++)
   {
   if(reg->abl != NULL)
	{
   	biabl = (biabl_list *) mbkalloc(sizeof(struct biabl)) ;

   	biabl->CNDABL = copyExpr(reg->cnd) ;
  	biabl->VALABL = copyExpr(reg->abl) ; 
    biabl->NEXT = NULL ;
    behReg = syf_beh_addbereg(behReg,reg->name,biabl,NULL,0) ;
    }
   reg++ ;
   }

}
beh->BEREG = behReg ;

	/* les signaux output */

if(autoSys->typeReg == REG_D)
	reg = autoSys->reg ;
else
	reg = autoSys->reg + autoSys->numberReg ;
behOut = NULL ;
for(i = 0; i < autoSys->numberReg; i++)
   {
   behOut=syf_beh_addbeout(behOut,nameVector("adr",i),createAtom(reg->name),NULL,0);
   out++ ;
   reg++ ;
   }
beh->BEOUT = behOut ;

beh->CIRCUI = pC ;
/*
beh->CIRCUI = createCir() ;
syf_makeBddBeh(beh,beh->CIRCUI,1,syf_trace,9) ;
*/
return(beh) ;

}
/*------------------------------------------------------------------------------
nameVector	: Cree un nom correspondant a un element d'un type vector de vbe.
--------------------------------------------------------------
parametres		: name, index
--------------------------------------------------------------
return			: nameIndex .
------------------------------------------------------------------------------*/
char *nameVector(name,index)
char *name ;
int index ;
{
char *nameI ;

nameI = mbkalloc(strlen(name) + 5) ;

sprintf(nameI,"%s %d",name,index) ;

return(nameI) ;
}
