
/****************************************************************************/
/*                                                                          */
/*                      Chaine de CAO & VLSI   Alliance                     */
/*                                                                          */
/*    Produit :  Synthetiseur de FSM                                       */
/*    Fichier :  syf_ame.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 : 04/03/1992     */
/*                                                                          */
/*    Modifie par :                                     le : ../../....     */
/*    Modifie par :                                     le : ../../....     */
/*    Modifie par :                                     le : ../../....     */
/*                                                                          */
/***************************************************************************/

#include <stdio.h>
#include <math.h>
#include MUT_H
#include LOG_H
#include "syf_auto.h"
#include "syf_must.h"
#include "../util/util.h"
/*--------------------------------------------------------------------------- musePoidFutur   : calcul le poids effectif de chaque couple d'etats .
---------------------------------------------------------------------
 parametres   : aucun .
--------------------------------------------------------------------
 return       : rien .
---------------------------------------------------------------------------*/
int *PoidsFutur()
{
int k,l;
pNode tabBdd[3];
int DIMS;
int *wf;
 
  DIMS = autoSys->numberState;
 wf = (int *)mbkalloc((autoSys->numberState + 1)* autoSys->numberState * sizeof(int )) ;

  for(k = 0; k < autoSys->numberState ; k++)
  {
    for(l = 0; l < autoSys->numberState ; l++)
    {
 /*    if(k!=l)
     {
     tabBdd[0] =(autoSys->state + k)->bdd;
     tabBdd[1] =(autoSys->state + l)->bdd;
     tabBdd[2] = NULL;
     wf[k*DIMS + l] = numberNodeMultiBdd(tabBdd);
     }
    else*/
     wf[k*DIMS +l] = 0;
    }
  }

return(wf);
}

/*---------------------------------------------------------------------------
calculCout           : regroupe tous les fonctions du codage mustang
---------------------------------------------------------------------------
parametres        : aucun
--------------------------------------------------------------------------
return            : rien .
---------------------------------------------------------------------------*/
unsigned int calculCout(cP,cF,Aff)
int *cP;
int *cF;
int *Aff;
{
int DIMS,i,j;
unsigned int Cout =0;
int numBit;
pCode code;

   code = autoSys->code;
  DIMS = autoSys->numberState;
  numBit = autoSys->numberReg;
  for(i=0; i < autoSys->numberState; i++)
  {
    Cout = Cout + cF[i]*numbit_1((code + i)->code,numBit);
    /*for(j=0; j < i ; j++)
    Cout = Cout + (cP[i*DIMS + j] + Aff[i*DIMS + j])*(distHaming((code+i)->code,(code + j)->code,numBit) -1);
	printf("Cout courant : %u\n",Cout) ;*/
	/*Cout = Cout/2;*//* le cout depasse la taille de unsigned int. On le diminue*/
  }  
  /*printf("cout estime' : %u\n",Cout);*/
  return(Cout);
}

int calculCoutState(cP,cF,Aff,stateLabel,newCode,tabCode)
int *cP;
int *cF;
int *Aff;
int stateLabel;
int newCode;
int *tabCode;
{
int DIMS,i;
int Cout =0;
int numBit;
int stateEx;
pCode code;

   code = autoSys->code;
  DIMS = autoSys->numberState;
  numBit = autoSys->numberReg;
  stateEx = tabCode[newCode];

  Cout = cF[stateLabel]*numbit_1(newCode,numBit);

  for(i=0; i < autoSys->numberState; i++)
  {
    if((i!= stateEx)&&(i!= stateLabel))
         Cout = Cout + (cP[stateLabel*DIMS + i] + Aff[stateLabel*DIMS + i])*(distHaming(newCode,(code + i)->code,numBit) -1);
    else if(i == stateEx)
         Cout = Cout + (cP[stateLabel*DIMS + i] + Aff[stateLabel*DIMS + i])*(distHaming(newCode,(code + stateLabel)->code,numBit) -1);
  }  
  return(Cout);
}
/*----------------------------------------------------------------
codeModification	:
-------------------------------------------------------
param				: cP : poid du a l'interaction entre etats.
					  cF : poid des etats.
-------------------------------------------------------
return				:
-------------------------------------------------------------------*/
int codeModification(cP,cF,Aff,tabCode,Se)
int *cP;
int *cF;
int *Aff;
int *tabCode;
p_groupe Se;
{
int DIMS,label,valCode;
int Cout =0;
int numBit,i;
int newCode ;
int stateEx;
int coutMax ;
int coutMin = 0;
int selectLabel ;
 p_groupe group;
pCode code;
 
newCode = -1;
coutMax = -1;
selectLabel = -1;

   code = autoSys->code;
  DIMS = autoSys->numberState;
  numBit = autoSys->numberReg;
  group = Se; 
    label = group->label;
    Cout = calculCoutState(cP,cF,Aff,label,(code +label)->code,tabCode); 
         coutMax = Cout;
         selectLabel = label ;
   group = group->next;
  while(group)
  {
    label = group->label;
    Cout = calculCoutState(cP,cF,Aff,label,(code +label)->code,tabCode); 
    if(Cout > coutMax)
       {
         selectLabel = label ;
         coutMax = Cout;
       }
   group = group->next;
  }
  for(valCode=0; valCode< bit[numBit]; valCode++)
  {
    stateEx = tabCode[valCode];
    if(stateEx < autoSys->numberState)
      {
       Cout = calculCoutState(cP,cF,Aff,selectLabel,valCode,tabCode) 
           + calculCoutState(cP,cF,Aff,stateEx,(code + selectLabel)->code,tabCode) 
              - calculCoutState(cP,cF,Aff,selectLabel,(code + selectLabel)->code,tabCode) 
              - calculCoutState(cP,cF,Aff,stateEx,valCode,tabCode); 
      }
    else 
       Cout = calculCoutState(cP,cF,Aff,selectLabel,valCode,tabCode) 
            - calculCoutState(cP,cF,Aff,selectLabel,(code + selectLabel)->code,tabCode) ;
    if((Cout < coutMin )&&(Cout < 0))
       {
         newCode = valCode;
         coutMin = Cout;
       }
  }

 
    if (( coutMin < 0)&&(selectLabel != -1))
    {
	/*printf("avant affectation\n") ;
	verifCode() ;
	displayCode(0) ;
	displayTabCode(tabCode,NUMBER_CODE(autoSys->numberState)) ;
	printf("NEW_CODE : %d\n",newCode) ;
	*/
      stateEx = tabCode[newCode];
	  /*printf("code[%d] = %d\n",stateEx,(autoSys->code + stateEx)->code) ;
	  printf("code[%d] = %d\n",selectLabel,(autoSys->code + selectLabel)->code);
	  */
       (autoSys->code + stateEx)->code = (autoSys->code + selectLabel)->code;
       (autoSys->code + selectLabel)->code = newCode;
       tabCode[newCode] = selectLabel;
       tabCode[(autoSys->code + stateEx)->code] = stateEx;
	 /* printf("code[%d] = %d\n",stateEx,(autoSys->code + stateEx)->code) ;
	  printf("code[%d] = %d\n",selectLabel,(autoSys->code + selectLabel)->code);
	printf("apres affectation\n") ;
	verifCode() ;
	*/
      }
 return(selectLabel);
}
