/****************************************************************************/
/*                                                                          */
/*                      Chaine de CAO & VLSI   Alliance                     */
/*                                                                          */
/*    Produit :  Synthetiseur de FSM                                       */
/*    Fichier :  syf_auto.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"
/*------------------------------------------------------------------------------
initializeAuto	: initialise les structures pour FSM .
--------------------------------------------------------------
parametres	: int : nombre de sorties,nombre d' states.
		  
--------------------------------------------------------------
return		: .
------------------------------------------------------------------------------*/
void initializeAuto(numberInput,numberOutput,numberState,sizeStack,numberCtrl)
int numberInput, numberOutput,numberState,sizeStack, numberCtrl ;
{
int i ;

numberState = numberState * 200 ;
autoSys = (pAutoSys)mbkalloc(sizeof(struct system)) ;

autoSys->input = (char **)mbkalloc((numberInput +2) * sizeof(char *)) ;

autoSys->state=(pState)mbkalloc((numberState +1)*sizeof(struct state)) ;

autoSys->out = (pOut) mbkalloc((numberOutput + 1) * sizeof(struct output)) ;

autoSys->regOut=(pReg)mbkalloc(2*(numberOutput + 1)* sizeof(struct Sregister)) ;

autoSys->inCtrl = (pCtrl) mbkalloc((numberCtrl + 1) * sizeof(struct output)) ;

autoSys->inStack = (pReg *)mbkalloc((sizeStack +3) * sizeof(pReg)) ;

autoSys->code = (pCode)mbkalloc(NUMBER_CODE(numberState) * sizeof(struct code));

autoSys->reg=(pReg)mbkalloc(2*(NUMBER_BIT(numberState))*sizeof(struct Sregister)) ;

for(i = 0; i < numberInput + 2; i++)
	*(autoSys->input + i) = NULL ;

for(i = 0; i < 2 * (NUMBER_BIT(numberState)); i++)
	{	
	(autoSys->reg + i)->name = NULL ;
	(autoSys->reg + i)->abl = NULL ;
	(autoSys->reg + i)->cnd = NULL ;
	(autoSys->reg + i)->bdd = NULL ;
	}
for(i = 0; i < 2*(numberOutput + 1); i++)
	{	
	(autoSys->regOut + i)->name = NULL ;
	(autoSys->regOut + i)->abl = NULL ;
	(autoSys->regOut + i)->cnd = NULL ;
	(autoSys->regOut + i)->bdd = NULL ;
	}
for(i = 0; i < numberOutput + 1; i++)
	{	
	(autoSys->out + i)->name = NULL ;
	(autoSys->out + i)->abl = NULL ;
	(autoSys->out + i)->bdd = NULL ;
	}
for(i = 0; i < numberState; i++)
	{
	(autoSys->state + i)->name = NULL ;
	(autoSys->state + i)->trans = NULL ;
	(autoSys->state + i)->locOut = NULL ;
	(autoSys->state + i)->locOutDc = NULL ;
	(autoSys->state + i)->abl = NULL ;
	(autoSys->state + i)->bdd = NULL ;
	(autoSys->state + i)->user = NULL ;
	}
for(i = 0; i < numberCtrl + 1; i++)
        {
        (autoSys->inCtrl+ i)->name = NULL ;
        (autoSys->inCtrl+ i)->abl = NULL ;
        (autoSys->inCtrl+ i)->bdd = NULL ;
        }
for(i = 0; i < sizeStack; i++)
	*(autoSys->inStack + i) = NULL ;
for(i = 0; i < NUMBER_CODE(numberState); i++)
	{
	(autoSys->code + i)->code = 0 ;
	(autoSys->code + i)->abl = NULL ;
	/*printf("cod[%d] = %d\n",i,(autoSys->code + i)->code) ;*/
	}
autoSys->typeReg = 0 ;
autoSys->stack = NULL ;
autoSys->inFixStack = NULL ;
autoSys->ablDc = NULL ;
autoSys->dc = NULL ;
autoSys->name = NULL ;
autoSys->codage = NULL ;
autoSys->horloge = NULL ;
autoSys->cndReg = NULL ;
autoSys->numberState = 0 ;
autoSys->numberReg = 0 ;
autoSys->numberCtrl = numberCtrl ;
autoSys->stackCodeMask  = -1 ;
autoSys->stackFixCode = 0 ;
autoSys->sizeStack = sizeStack ;
autoSys->stackNumBit = NUMBER_BIT(numberState) ;
autoSys->numberIn = 0 ;
autoSys->numberOut = 0 ;
autoSys->typeMachine = MOORE ;
autoSys->scin = NULL ;
autoSys->scout = NULL ;
autoSys->testMode = NULL ;
}

/*------------------------------------------------------------------------------
createState	: alloue et remplie la structure "ETAT".
--------------------------------------------------------------
parametres	: name : nom d'state . 
		  trans : une liste des "TRANSITIONS":pTarans .
--------------------------------------------------------------
return		: int .
------------------------------------------------------------------------------*/
int createState(name,trans,locOut,locOutDc)
char *name ;
pTrans trans;
pLocOut locOut;
pLocOut locOutDc;
{
pState state ;
int i, label ;

for(i = 0; i < autoSys->numberState; i++)
   if(!strcmp((autoSys->state + i)->name,name))
     {
      state =autoSys->state + i ;
      return(i); 
     }

state = (pState)mbkalloc(sizeof(struct state)) ;

state = autoSys->state + autoSys->numberState;
state->trans = trans ;
state->locOut = locOut ;
state->locOutDc = locOutDc ;
state->name = name;
state->user = NULL ;
autoSys->numberState++ ;
return(i) ;
}
/*------------------------------------------------------------------------------
createTrans	: Alloue une structure "PTRANS", et le remplie .
--------------------------------------------------------------
parametres	: out : pointeur sur la structure "OUTPUT" .
		  abl : abl de la fonction de transition .
		  sP : state precedent .
--------------------------------------------------------------
return		: le pointeur sur la structure cree .
------------------------------------------------------------------------------*/
pTrans createTrans(abl,sPlabel)
chain_list *abl ;
int sPlabel ;
{
pTrans trans ;

trans = (pTrans)mbkalloc(sizeof(struct transition)) ;

trans->abl = copyExpr(abl) ;
trans->sPlabel = sPlabel ;
trans->next = NULL ;
trans->bdd = NULL ;
return(trans) ;
}
/*------------------------------------------------------------------------------
createLocOutDc	: Alloue une structure "OUTPUT", et le remplie .
--------------------------------------------------------------
parametres	: name : nom de la sortie.
		  abl : abl de la fonction de generation .
--------------------------------------------------------------
return		: le pointeur sur la structure cree .
------------------------------------------------------------------------------*/
pLocOut createLocOutDc(stlabel,name,abl)
int stlabel;
char *name ;
chain_list *abl ;
{
pLocOut outAux ;
pLocOut locOutDc;
pState state;
int label ;


label = addOut(name) ;
if(stlabel !=-1)
 {
state= autoSys->state;
  locOutDc = (state + stlabel)->locOutDc;
  while(locOutDc)
  {
   if(locOutDc->label == label)
      {
         addQExpr(locOutDc->abl,copyExpr(abl));
         return(locOutDc);
      }
   locOutDc = locOutDc->next;   
  }
  outAux = (pLocOut)mbkalloc(sizeof(struct locOutput)) ;

  locOutDc = (state + stlabel)->locOutDc;

  outAux->label = label ;
  outAux->abl = createExpr(OR);
  addQExpr(outAux->abl ,createAtom("'0'")); 
  addQExpr(outAux->abl ,copyExpr(abl)); 
  outAux->next = locOutDc ;
  (state+stlabel)->locOutDc = outAux;
  return((state + stlabel)->locOutDc);
 }
}
/*------------------------------------------------------------------------------
createLocOut	: Alloue une structure "OUTPUT", et le remplie .
--------------------------------------------------------------
parametres	: name : nom de la sortie.
		  abl : abl de la fonction de generation .
--------------------------------------------------------------
return		: le pointeur sur la structure cree .
------------------------------------------------------------------------------*/
pLocOut createLocOut(stlabel,name,abl)
int stlabel;
char *name ;
chain_list *abl ;
{
pLocOut outAux ;
pLocOut locOut;
pOut out;
pState  state;
int label ;

if((strcmp((char *)abl->DATA,"'1'") && strcmp((char *)abl->DATA,"'0'"))||stlabel == -1)
	autoSys->typeMachine = MEALEY ;
label = addOut(name) ;
if(stlabel !=-1)
 {
state= autoSys->state ;
 /* locOut = (state + stlabel)->locOut;
  while(locOut)
  {
   if(locOut->label == label)
      {
         addQExpr(locOut->abl,copyExpr(abl));
         return((state+stLabel)->locOut);
      }
   locOut = locOut->next;   
  }*/
  outAux = (pLocOut)mbkalloc(sizeof(struct locOutput)) ;

  locOut =(state+stlabel)->locOut;

  /*outAux->abl = createExpr(OR);*/
  outAux->abl = copyExpr(abl);
  outAux->label = label;
  /*addQExpr(outAux->abl ,copyExpr(abl));*/ 
  outAux->next = locOut ;
  (state+stlabel)->locOut = outAux;
  return((state +stlabel)->locOut);
 }
else 
 {
   out = autoSys->out + label;
   if(out->abl)
    {
       addQExpr(out->abl,copyExpr(abl)); 
       return(NULL);
    }
   else
    {
      out->abl = createExpr(OR);
      addQExpr(out->abl ,copyExpr(abl)); 
      return(NULL);
    }
 } 
}
/*------------------------------------------------------------------------------
addStack        : Alloue une structure "pStack", et le remplie .
--------------------------------------------------------------
parametres      : out : pointeur sur la structure "OUTPUT" .
                  abl : abl de la fonction de transition .
                  sP : state precedent .
--------------------------------------------------------------
return          : le pointeur sur la structure cree .
------------------------------------------------------------------------------*/
pStack addStack(ctrl,curentStatelabel,returnStatelabel,abl)
int ctrl;
int curentStatelabel;
int returnStatelabel;
chain_list *abl ;
{
pStack stackAux ;
pStack stack;
 
stackAux = (pStack)mbkalloc(sizeof(struct stack)) ;
 
 stack = autoSys->stack;
stackAux->abl = copyExpr(abl) ;
stackAux->ctrl = ctrl ;
stackAux->curentStatelabel = curentStatelabel ;
stackAux->returnStatelabel = returnStatelabel ;
stackAux->next = stack ;
stack = stackAux;
autoSys->stack = stack;
return(stack);
}

/*------------------------------------------------------------------------------
addName			: ajoute une chaine de caractere dans un tableau de 
			  pointeur sur la chaine de caractere .
--------------------------------------------------------------
parametres		: tab   : tableau de poineur sur (char *) .
		  	  name  : chaine de caractere a ajouter en fin de liste.
--------------------------------------------------------------
return			: un label .
------------------------------------------------------------------------------*/
int addName(tab,name,size)
char **tab ;
char *name ;
int *size;
{
int i;

for(i = 0; i < *size; i++)
	if(strcmp(tab[i],name) == 0)
		return(i) ;

tab[i] = namealloc(name) ;
/*tab[i+1] = NULL ;*/
(*size)++ ;
return(i) ;
}
/*------------------------------------------------------------------------------
addOut			: ajoute une sortie dans autoSys si elle n'existe pas
			  deja . 
--------------------------------------------------------------
parametres		: name  : nom de la sortie . 
--------------------------------------------------------------
return			: un label .
------------------------------------------------------------------------------*/
int addOut(name)
char *name ;
{
int i;

for(i = 0; i < autoSys->numberOut; i++)
	{
	if(!(strcmp((autoSys->out + i)->name,name)))
		return(i) ;
	}
(autoSys->out +i)->name = namealloc(name) ;
autoSys->numberOut++ ;
return(i) ;
}
/*------------------------------------------------------------------------------
addState		: ajoute un etat dans la table des STATES de autoSys . 
--------------------------------------------------------------
parametres		: name  : nom d'etat .
			  state : pointeur sur etat .
--------------------------------------------------------------
return			: label d'etat .
------------------------------------------------------------------------------*/
int addState(name)
char *name ;
{
int i;

for(i = 0; i < autoSys->numberState; i++)
	{
	if(!(strcmp((autoSys->state + i)->name,name)))
		return(-1) ;
	}
(autoSys->state + i)->name = namealloc(name);
autoSys->numberState++;
return(i) ;
}
/*------------------------------------------------------------------------------
ajoutOut		: ajoute une nouvelle structure LocOutput en TOP de 
                          la liste state->locOut.
--------------------------------------------------------------
parametres		: state : l'etat sur lequel s'effectue l'operation .
--------------------------------------------------------------
return			: rien .
------------------------------------------------------------------------------*/
void ajoutLocOut(state,locOut,locOutDc)
pState state ;
pLocOut locOut;
pLocOut locOutDc;
{
if(locOutDc)
 {
   locOutDc->next = state->locOutDc ;
   state->locOutDc = locOutDc ;
 }
if(locOut)
 {
  locOut->next = state->locOut ;
  state->locOut = locOut ;
 }
}
/*------------------------------------------------------------------------------
ajoutTrans		: ajoute une nouvelle structure TRANSITION en TOP de la
			  liste state->trans.
--------------------------------------------------------------
parametres		: state : l'etat sur lequel s'effectue l'operation .
--------------------------------------------------------------
return			: rien .
------------------------------------------------------------------------------*/
void ajoutTrans(stlabel,trans)
int stlabel ;
pTrans trans ;
{
if(trans)
 {
   trans->next = (autoSys->state + stlabel)->trans ;
   (autoSys->state+stlabel)->trans = trans ;
 }
else printf("erreur TRANS NULL!!!\n");
}
/*------------------------------------------------------------------------------
saveOut			: Regenere une autre structure out identique a celle passe en
				  parametre.
--------------------------------------------------------------
parametres		: struct out .
--------------------------------------------------------------
return			: nouvelle struct .
------------------------------------------------------------------------------*/
pOut saveOut(out)
pOut out ;
{
pOut outCur, newOut;
int i ;
 
newOut = (pOut) mbkalloc((autoSys->numberOut + 1) * sizeof(struct output)) ;

outCur = newOut ;
for(i = 0; i < autoSys->numberOut; i++)
	{
	outCur->name = namealloc(out->name) ;
	if(out->abl == NULL)
		outCur->abl = NULL ;
	else
		outCur->abl = copyExpr(out->abl) ;
	outCur->bdd = out->bdd ;
	out++ ;
	outCur++ ;
	}
return(newOut) ;
}
/*------------------------------------------------------------------------------
freeOut			: Libere la memoire allouee pour autoSys->out.
--------------------------------------------------------------
parametres		: struct out .
--------------------------------------------------------------
return			: rien .
------------------------------------------------------------------------------*/
freeOut(out)
pOut out ;
{
int i;

for(i = 0; i < autoSys->numberOut; i++)
	{
	/*Ne jamais liberer out->name, ni aucune chaine allouee pas namealloc*/
	freeExpr(out->abl) ;
	out++ ;
	}
}
/*------------------------------------------------------------------------------
freeTrans	: desaloue la list des structures "PTRANS" .
--------------------------------------------------------------
parametres	: trans
--------------------------------------------------------------
return		: .
------------------------------------------------------------------------------*/
freeTrans(trans)
pTrans trans ;
{
pTrans curTrans, trans2 ;

curTrans = trans ;
while(curTrans)
	{
	freeExpr(curTrans->abl) ;
	trans2 = curTrans->next ;
	free(curTrans) ;
	curTrans = trans2 ;
	}
}
/*------------------------------------------------------------------------------
getTypeMachine	: Determine le type de la machine MOORE ou MEALEY.
--------------------------------------------------------------
parametres	: 
--------------------------------------------------------------
return		: 
------------------------------------------------------------------------------*/
getTypeMachine()
{
pLocOut locOut, locOut2;
pState state ;
int i ;

if(syf_trace)
	printf("----- getTypeMachine -----\n") ;
autoSys->typeMachine = MOORE ;

state = autoSys->state ;
for(i = 0; i < autoSys->numberState; i++)
     {
	 locOut = state->locOut ;
	 while(locOut)
		{
		locOut2 = locOut->next ;
		while(locOut2)
			{
			if(locOut->label == locOut2->label &&
						!equalExpr(locOut->abl,locOut2->abl))
				{
				autoSys->typeMachine = MEALEY ;
				return(MEALEY) ;
				}
			locOut2 = locOut2->next ;
			}
		locOut = locOut->next ;
		}
     state++ ;
     }
}
