
/****************************************************************************/
/*                                                                          */
/*                      Chaine de CAO & VLSI   Alliance                     */
/*                                                                          */
/*    Produit :  Synthetiseur de FSM                                       */
/*    Fichier :  syf_init.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"../beh104/beh104.h"
#include "syf_must.h"
#include "syf_beh2fsm.h"
#include "syf_auto.h"

#define HSHSIZE 37
char *findClock(beh)
struct syf_befig *beh;
{
return(namealloc("ck"));
}
defaultName(beh)
struct syf_befig *beh;
{
 flagPile =0;
CLOCK = findClock(beh);
CURENT_STATE = namealloc("curent_state");
RETURN_STATE = namealloc("RETURN_STATE");
NEXT_STATE   = namealloc("next_state");
CTRL = namealloc("CTRL");
ctrlName = (char **)mbkalloc((NUMBERCTRL) * sizeof(char *)) ;

  ctrlName[0] = namealloc("nop");
  ctrlName[1] = namealloc("push");
  ctrlName[2] = namealloc("pop");
}

initInOutST(beh)
struct syf_befig *beh;
{
 struct syf_bepor *pBepor;
 struct syf_beaux *pBeaux;
 struct syf_betyp *pBetype;
 struct ptype  *pType;
 struct syf_bepgm *pBepgm;
 struct syf_bepcs *pBepcs;

 char *SYF = namealloc("SYF");
 char *name;
 int  valu;
 int numberIn = 0;
 int numberCtrl = 0;
 int sizeStack = -1; /******* p t 0 ******/
 int numberOut = 0;
 int numberState = 0;
 int numberType,i;

   defaultName(beh);
   hshtab = addht(HSHSIZE);
  pBepgm = beh->BEPGM ;
  while(pBepgm) /* Les pragmas de scan-path sont apres initializeAuto */
  {
    if(pBepgm->TOOL== SYF && pBepgm->NAME)
    {
    if(!(strcmp(pBepgm->TYPE, namealloc("CUR_STATE"))))
 		CURENT_STATE = pBepgm->NAME ;	
    else if(pBepgm->TYPE == namealloc("NEX_STATE"))
 		NEXT_STATE = pBepgm->NAME ;	
    else if(pBepgm->TYPE == namealloc("CTRL"))
 		CTRL = pBepgm->NAME ;	
    else if(pBepgm->TYPE == namealloc("NOP"))
 		ctrlName[0] = pBepgm->NAME ;	
    else if(pBepgm->TYPE == namealloc("PUSH"))
 		ctrlName[1] = pBepgm->NAME ;	
    else if(pBepgm->TYPE == namealloc("POP"))
 		ctrlName[2] = pBepgm->NAME ;	
    }
   pBepgm = pBepgm->NEXT;
  }

  pBeaux = beh->BEAUX;
  while(pBeaux ) 
  {
    if(!(strcmp(pBeaux->NAME ,  CURENT_STATE)))
	ETAT_TYPE = (beh->BETYP + pBeaux->TYPE -1)->NAME; 
    else if(pBeaux->NAME ==  CTRL)
	CTRL_TYPE = (beh->BETYP + pBeaux->TYPE -1)->NAME;
   pBeaux = pBeaux->NEXT;
  }

  pBepor = beh->BEPOR;
  while(pBepor)
  {
    switch(pBepor->DIRECTION)
    {
     case  'I' : numberIn++;
                 break;
     case  'Z' : 
     case  'O' : numberOut++;
                 break;
     case  'B' : 
     case  'T' : numberOut++;
                 numberIn++;
                 break;
    }
  pBepor = pBepor->NEXT;
  }
  pBetype = beh->BETYP;
  while(pBetype)
  {
    if(pBetype->NAME == ETAT_TYPE)
        numberState = pBetype->SIZE;
    else if(pBetype->NAME == CTRL_TYPE)
	{
		numberCtrl =pBetype->SIZE;
		flagPile =1;
	}
	pBetype = pBetype->NEXT;
  }
  if(numberCtrl !=3 && numberCtrl !=0)
	printf("illegal number of controle type\n");

  if(numberState == 0)
	{
	printf("SyF : number of states is zero\n");
	exit(-1);
	}
  if(flagPile ==1)
  {
  pBepcs = beh->BEPCS;
    while(pBepcs)
    {
      pType = pBepcs->INSTRUCTION;
       sizeStack += stack_verify(beh,pType,0);
     pBepcs = pBepcs->NEXT;
    }
  }
 initializeAuto(numberIn+1,numberOut,numberState,sizeStack,NUMBERCTRL,2); 

  pBepgm = beh->BEPGM ;
  while(pBepgm)
  {
    if(pBepgm->TOOL== SYF && pBepgm->NAME)
    {
    if(pBepgm->TYPE == namealloc("TEST_MODE"))
 		autoSys->testMode = pBepgm->NAME ;	
    else if(pBepgm->TYPE == namealloc("SCIN"))
 		autoSys->scin = pBepgm->NAME ;	
    else if(pBepgm->TYPE == namealloc("SCOUT"))
 		autoSys->scout = pBepgm->NAME ;	
    }
   pBepgm = pBepgm->NEXT;
  }

 autoSys->horloge = namealloc(CLOCK);
  pBepor = beh->BEPOR;
  while(pBepor)
  {
    switch(pBepor->DIRECTION)
    {
     case  'I' : addName(autoSys->input,pBepor->NAME,&autoSys->numberIn);
                 break;
     case  'Z' : 
     case  'O' : addOut(pBepor->NAME);
                 break;
     case  'B' : 
     case  'T' : addOut(pBepor->NAME);
                 addName(autoSys->input,pBepor->NAME,&autoSys->numberIn);
                 break;
    }
  pBepor = pBepor->NEXT;
  }
  if( flagPile ==1)
   {
	 STACK_NAME = (char **)mbkalloc((sizeStack) * sizeof(char *)) ;
  if((valu =gethtitem(hshtab,RETURN_STATE)) !=EMPTYHT)
  {
	i =0;
     while((name =((pValu)valu)->pere) != NULL)
	{
          STACK_NAME[i++] = namealloc(name); 
          if((valu = gethtitem(hshtab,name))  == EMPTYHT) 
  		printf("erreur \n");
        }
  }
 }
  pBetype = beh->BETYP;
  while(pBetype)
  {
    if(pBetype->NAME == ETAT_TYPE)
		 for(i =0; i< pBetype->SIZE; i++)
	     if(addState(*(pBetype->VALUE +i))== -1) 
		   {
		     printf(" %s have been declared more than one !!!\n",*(pBetype->VALUE +i));
             exit(-1);
		   }
		  
  pBetype = pBetype->NEXT;
  }
  autoSys->numberReg = NUMBER_BIT(autoSys->numberState);
 }  
/*------------------------------------------------------------------------------*/
/*   stack_verify 	: verifie l'integrete de l'affectation des piles	*/
/*------------------------------------------------------------------------------*/
/*   argument 		: pType (liste d'instructions) , flag 		 	*/
/*------------------------------------------------------------------------------*/
/*   return 		: rien							*/
/*------------------------------------------------------------------------------*/

  int stack_verify(beh,pType,flag)
  struct syf_befig *beh;
  struct ptype *pType;
  unsigned char flag;
  {
   struct ptype *type_pnt;
   struct syf_betyp *pBetyp; 
   struct syf_becas *pBecas; 
   struct syf_beifs *pBeifs; 
   struct syf_beasg *pBeasg; 
   char   *name1;
   char   *name2;
   int   size =0; 
   int valu,i;
   int flagAux;
     
    flagAux = flag;
    type_pnt = pType;
    while(type_pnt)
    {
    switch(type_pnt->TYPE)
    {
    case BEH_BECAS : pBecas = (struct syf_becas *)type_pnt->DATA;
                     pBetyp = beh->BETYP +  pBecas->TYPE -1;
                     if((!strcmp(pBetyp->NAME , CTRL_TYPE))&&
                     ATOM(pBecas->ABL) &&
                     (!strcmp(VALUE_ATOM(pBecas->ABL),CTRL)))
                    {
                     for(i=0; i< (int) pBecas->SIZE -1;i++)
			{
			if((flagAux = labelCtrl(pBetyp->VALUE[syf_bintonum((pBecas->CHOICE[i]).VALUE)])) == -1)
			flagAux = 0;
                        size +=stack_verify(beh,(pBecas->CHOICE[i]).INSTRUCTION,flagAux);
			}
                    }
		      break;
   case BEH_BEIFS  :  pBeifs =(struct syf_beifs*) type_pnt->DATA; 
	        	size += stack_verify(beh,pBeifs->CNDTRUE,flagAux); 
	        	size += stack_verify(beh,pBeifs->CNDFALSE,flagAux); 
   case BEH_BEMSG  :  break; 
   case BEH_BEASG  : if(flag != 0) 
		     {
    			   pBeasg = (struct syf_beasg *)type_pnt->DATA;
                     pBetyp = beh->BETYP +  pBeasg->TYPE -1;
                     if((!strcmp(pBetyp->NAME , ETAT_TYPE))&&
                     ATOM(pBeasg->ABL)) 
			{
			 if( flag == PUSH)
			 {
				name1 = pBeasg->NAME;
				name2 = VALUE_ATOM(pBeasg->ABL);
			 }
			else 
			 {
				name2 = pBeasg->NAME;
				name1 = VALUE_ATOM(pBeasg->ABL);
			 }
			}
                         if((valu = gethtitem(hshtab,name1))== EMPTYHT)
				{
				size++ ;
			   addelement(name1,NULL,name2);
				}
			 else if( !(((pValu) valu)->fils)) 
			 ((pValu)valu)->fils = name2;
			 else
			  if(name2 != ((pValu) valu)->fils)	
			   {
			    printf("erreur d'affectation au signal : %s\n",name1);
			   }

                         if((valu = gethtitem(hshtab,name2))== EMPTYHT)
				{
				size++ ;
			   addelement(name2,name1,NULL);
				}
			 else if( !(((pValu) valu)->pere)) 
			 ((pValu)valu)->pere = name1;
			 else
			  if(name1 != ((pValu) valu)->pere)	
			   {
			    printf("erreur d'affectation au signal : %s\n",name1);
			   }
   			}
     }
   type_pnt = type_pnt->NEXT;
   }
 return(size);
 }

 void addelement(keyname,pere,fils) 
 char *keyname;
 char *pere;
 char *fils;
 {
   pValu DATA;
 
   DATA = (pValu)mbkalloc(sizeof(struct valu)) ;

   DATA->pere = pere;
   DATA->fils = fils;
   addhtitem(hshtab,keyname,(int)DATA);
  
 }

 struct chain *andExpr(name,binValue,left,right)
 char *name;
 char *binValue;
 int   left;
 int   right;
  { 
  int flag = 1;
  int i, n=0;
  char tmp[30];
  struct chain* abl;
  struct chain* ATOM_ABL;

  if (( left >= right &&strlen(binValue) != left -right +1)||
     ( left <= right &&strlen(binValue) != right -left +1))
    {
    printf( "andExpr erreur : le vecteur et la chaine binaire n'ont pas \n la meme taille\n"); 
     exit(-1);
    }
   if (left > right) 
 	 flag = -1;
  abl = createExpr(AND);
  for(i = left; i != right + flag  ; i+= flag)
  {
      sprintf(tmp,"%s(%d)",name,i); 
      ATOM_ABL = createAtom(tmp); 
      if(binValue[n++] == '0')
         ATOM_ABL = notExpr(ATOM_ABL);
      addQExpr(abl,ATOM_ABL);
  }
  return(abl);
 } 
