/****************************************************************************/
/*                                                                          */
/*                      Chaine de CAO & VLSI   Alliance                     */
/*                                                                          */
/*    Produit :  Synthetiseur de FSM                                       */
/*    Fichier :  syf_jedi.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 : 10/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"



/*---------------------------------------------------------------------------
choixJedi         : genere l'etat qui va etre coder a la
                    prochaine iteration .
---------------------------------------------------------------------------
parametres        : aucun
--------------------------------------------------------------------------
return            : rien .
---------------------------------------------------------------------------*/
 void choixJedi(we)
 int *we;
 {
 int numberBit;
 pCode code;
 pCode dc;
 int *tabCode;
 int i;
 p_groupe Su;
 p_groupe Sa = NULL;
 int DIMS;

 numberBit = autoSys->numberReg;
 DIMS = autoSys->numberState;

 tabCode = (int*)mbkalloc(bit[numberBit] * sizeof(int)) ;
 for  (i = 0; i < bit[numberBit]; i++)
  tabCode[i] = bit[numberBit];

 code = autoSys->code;
 
 Su = stateGeneration();

 while(Su)
 {
  p_groupe ggu;
  int selectLabel;
  int maxW = 0;
 
  ggu = Su;
  selectLabel = ggu->label;

  while(ggu)
  { 
   p_groupe gga; 
   int cout = 0;
   int courantLabel = ggu->label;
  
  if (Sa == NULL) gga = Su; 
  else gga =Sa;

   while(gga)
   {
    int label = gga->label;
   
    cout += we[courantLabel*DIMS +label];
    gga = gga->next; 
   }
   if (cout > maxW)
    {
      maxW = cout; 
      selectLabel = courantLabel;
    }
   ggu = ggu->next;
  }
  jediCodage(selectLabel, tabCode, Sa,we);
  Su = delFromgroup(Su,selectLabel);
  Sa = addTogroup(Sa,selectLabel);
 }
 dc = autoSys->dc;
 for(i = 0; i < bit[numberBit]; i++)
 {
 if(tabCode[i] == bit[numberBit])
   {
   dc->code = i;
   dc++;
   }
 }
}


/*---------------------------------------------------------------------------
jediCodage        : attribue un code a l'element selectionner .
---------------------------------------------------------------------------
parametres        : l'etat selectionner et la table des codes
--------------------------------------------------------------------------
return            : rien .
---------------------------------------------------------------------------*/
 void jediCodage(selectLabel,tabCode, Sa,we)
 int selectLabel;
 int *tabCode;
 p_groupe Sa;
 int *we;
 {
  int numberBit;
  pCode code;
  p_groupe gga;
  int codeSa;
  int cout =0 ;
  int i,val= -1;
  int DIMS;
  int selectCode;

 
  numberBit = autoSys->numberReg;
  code = autoSys->code;

   gga = Sa;
  DIMS = autoSys->numberState;
   if (gga == NULL) 
    {
     (code + selectLabel)->code = 0;
     tabCode[0] = selectLabel;
     return ;
    }

  for( i =0; i< bit[numberBit]; i++)
  {
   if (tabCode[i]== bit[numberBit])
   {
   while(gga)
   {
    codeSa = (code + gga->label)->code;
    cout += we[gga->label*DIMS +selectLabel] * distHaming(codeSa,i,numberBit);
    gga= gga->next;
   }
   if ((cout < val)||(val == -1 )) 
     {
      selectCode = i;
      val = cout;
     }
   }  
  }
  (code + selectLabel)->code = selectCode;
  tabCode[selectCode] =  selectLabel;
 }
/*---------------------------------------------------------------------------
mustJedi           : regroupe tous les fonctions du codage mustang + Jedi
---------------------------------------------------------------------------
parametres        : aucun
--------------------------------------------------------------------------
return            : rien .
---------------------------------------------------------------------------*/
mustJedi()
{
 int *we;
 int *nwS;
 int *nwO;

nwS = (int *)mbkalloc((autoSys->numberState +1 )*(autoSys->numberState +1)  * sizeof(int )) ;
nwO = (int *)mbkalloc((autoSys->numberState + 1)*(autoSys->numberOut) * sizeof(int )) ;
 
 autoSys->dc  = autoSys->code + autoSys->numberState;
 
mustPoids(nwS,nwO);

we = mustCalcul(nwS,nwO);	
choixJedi(we);
/*#ifndef ARCHI_PC*/
free(we);
free(nwS);
free(nwO);
/*#endif*/
}
