/*------------------------------------------------------------\
|                                                             |
| This file is part of the Alliance CAD System Copyright      |
| (C) Laboratoire LIP6 - Département ASIM Universite P&M Curie|
|                                                             |
| Home page      : http://www-asim.lip6.fr/alliance/          |
| E-mail         : mailto:alliance-users@asim.lip6.fr       |
|                                                             |
| This progam is  free software; you can redistribute it      |
| and/or modify it under the  terms of the GNU General Public |
| License as  published by the Free Software Foundation;      |
| either version 2 of the License, or (at your option) any    |
| later version.                                              |
|                                                             |
| Alliance VLSI  CAD System  is distributed  in the hope that |
| it  will be useful, but WITHOUT  ANY WARRANTY;              |
| without even the  implied warranty of MERCHANTABILITY or    |
| FITNESS FOR A PARTICULAR PURPOSE. See the GNU General       |
| Public License for more details.                            |
|                                                             |
| You should have received a copy  of the GNU General Public  |
| License along with the GNU C Library; see the file COPYING. |
| If not, write to the Free Software Foundation, Inc.,        |
| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.                     |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
|                                                             |
| Tool    :                     SYF                           |
|                                                             |
| File    :                  syf_synth.c                      |
|                                                             |
| Authors :                  C. Sarwary                       |
|                     Modified by Jacomme Ludovic             |
|                                                             |
| Date    :                   01.11.94                        |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
|                                                             |
|                         Include Files                       |
|                                                             |
\------------------------------------------------------------*/

# include "mut.h"
# include "aut.h"
# include "abl.h"
# include "bdd.h"
# include "fsm.h"

# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include "syf_fsm.h"
# include "syf_error.h"
# include "syf_dc.h"
# include "syf_synth.h"

/*------------------------------------------------------------\
|                                                             |
|                           Constants                         |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
|                                                             |
|                            Types                            |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
|                                                             |
|                          Variables                          |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
|                                                             |
|                          Functions                          |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
|                                                             |
|                      SyfSynthReturn2Abl                     |
|                                                             |
\------------------------------------------------------------*/

void SyfSynthReturn2Abl( FsmFigure )

  fsmfig_list *FsmFigure;
{
  fsmstack_list *ScanStack;
  syfstate      *ReturnSyfState;
  syfstate      *CurrentSyfState;
  syfinfo       *SyfInfo;
  ablexpr    *Equation;
  ablexpr    *Atom;

  SyfInfo = FSM_SYF_INFO( FsmFigure );

  if ( ! SyfInfo->STACK ) return;

  for ( ScanStack  = FsmFigure->STACK;
        ScanStack != (fsmstack_list *)0;
        ScanStack  = ScanStack->NEXT )
  {
    if ( ScanStack->CTRL == FSM_CTRL_PUSH )
    {
      ReturnSyfState  = FSM_SYF_STATE( ScanStack->RETURN  );

      if ( IsFsmStarStack( ScanStack ) )
      {
        Equation = dupablexpr( ScanStack->ABL );
      }
      else
      {
        CurrentSyfState = FSM_SYF_STATE( ScanStack->CURRENT );

        Atom = createablatom( CurrentSyfState->CURRENT_NAME );
        Equation = optimablbinexpr( ABL_AND, 
                                     dupablexpr( ScanStack->ABL ),
                                     Atom );
      }

      if ( ReturnSyfState->ABL_RETURN == (ablexpr *)0 )
      {
        ReturnSyfState->ABL_RETURN = createabloper( ABL_OR );
      }

      addablhexpr( ReturnSyfState->ABL_RETURN, Equation );
    }
  }

  for ( ScanStack  = FsmFigure->STACK;
        ScanStack != (fsmstack_list *)0;
        ScanStack  = ScanStack->NEXT )
  {
    if ( ScanStack->CTRL == FSM_CTRL_PUSH )
    {
      ReturnSyfState = FSM_SYF_STATE( ScanStack->RETURN );
      Equation       = ReturnSyfState->ABL_RETURN;

      if ( ( Equation             != (ablexpr *)0 ) &&
           ( ABL_CDDR( Equation ) == (ablexpr *)0 ) )
      {
        Atom = ABL_CADR( Equation );
        ABL_CADR_L( Equation ) = (ablexpr *)0;
        freeablexpr( Equation );
        ReturnSyfState->ABL_RETURN = Atom;
      }
    }
  }
}

/*------------------------------------------------------------\
|                                                             |
|                   SyfSynthFreeReturnAbl                     |
|                                                             |
\------------------------------------------------------------*/

void SyfSynthFreeReturnAbl( FsmFigure )

  fsmfig_list *FsmFigure;
{
  syfinfo       *SyfInfo;
  syfstate      *ReturnSyfState;
  fsmstack_list *ScanStack;

  SyfInfo = FSM_SYF_INFO( FsmFigure );

  if ( SyfInfo->STACK )
  {
    for ( ScanStack  = FsmFigure->STACK;
          ScanStack != (fsmstack_list *)0;
          ScanStack  = ScanStack->NEXT )
    {
      if ( ScanStack->CTRL == FSM_CTRL_PUSH )
      {
        ReturnSyfState = FSM_SYF_STATE( ScanStack->RETURN  );

        if ( ReturnSyfState->ABL_RETURN != (ablexpr *)0 )
        {
          delablexpr( ReturnSyfState->ABL_RETURN );
          ReturnSyfState->ABL_RETURN = (ablexpr *)0;
        }
      }
    }
  }
}

/*------------------------------------------------------------\
|                                                             |
|                      SyfSynthStack2Abl                      |
|                                                             |
\------------------------------------------------------------*/

void SyfSynthStack2Abl( FsmFigure )

  fsmfig_list *FsmFigure;
{
  fsmstack_list *ScanStack;
  syfstate      *ReturnSyfState;
  syfinfo       *SyfInfo;
  syfregstack   *StackArray;
  syfregstack   *StackNextArray = NULL;
  syfregstack   *StackPrevArray;
  syfctrl       *CtrlArray;
  long           Constant;
  long           StackMask;
  long           StackNewMask;
  long           StackCste;
  long           StackNewCste;
  long           ScanBit;
  long           BitMask;
  long           Index;
  ablexpr    *Stack;
  ablexpr    *Equation;
  ablexpr    *ScanPath;
  ablexpr    *Atom;
  char          *PrevStack;
  char           Encode;

  SyfInfo = FSM_SYF_INFO( FsmFigure );
  Encode  = SyfInfo->ENCODE;

  if ( ! SyfInfo->STACK ) return;

//RegArray   = SyfInfo->REG_ARRAY;
  CtrlArray  = SyfInfo->CTRL_ARRAY;
  StackArray = SyfInfo->STACK_ARRAY;
  StackCste  = -1;
  StackMask  = 0;

  if ( Encode != SYF_ENCODE_ONE_HOT )
  {
    for ( ScanStack  = FsmFigure->STACK;
          ScanStack != (fsmstack_list *)0;
          ScanStack  = ScanStack->NEXT )
    {
      if ( ScanStack->CTRL == FSM_CTRL_PUSH )
      {
        ReturnSyfState  = FSM_SYF_STATE( ScanStack->RETURN  );
        StackNewCste    = ReturnSyfState->CODE->VALUE;

        if ( StackCste == -1 )
        {
          StackCste = StackNewCste;
          StackMask = -1;
        }
        else
        {
          StackNewMask = ~(StackCste ^ StackNewCste);
          StackMask    = StackMask & StackNewMask;
        }
      }
    }

/*
**  Push state in Stack_0 equation
*/
    for ( ScanBit = 0; ScanBit < SyfInfo->NUMBER_REG; ScanBit++ )
    {
      StackArray[ ScanBit ].ABL = createabloper( ABL_OR );
    }

    for ( ScanStack  = FsmFigure->STACK;
          ScanStack != (fsmstack_list *)0;
          ScanStack  = ScanStack->NEXT )
    {
      if ( ScanStack->CTRL == FSM_CTRL_PUSH )
      {
        ReturnSyfState = FSM_SYF_STATE( ScanStack->RETURN );
        StackNewCste   = ReturnSyfState->CODE->VALUE;

        BitMask = 1;

        for ( ScanBit = 0; ScanBit < SyfInfo->NUMBER_REG; ScanBit++ )
        {
          if ( BitMask & StackNewCste )
          {
            Atom = createablatom( ReturnSyfState->RETURN_NAME );

            addablhexpr( StackArray[ ScanBit ].ABL, Atom );
          }

          BitMask = BitMask << 1;
        }
      }
    }

    for ( ScanBit = 0; ScanBit < SyfInfo->NUMBER_REG; ScanBit++ )
    {
      Equation = StackArray[ ScanBit ].ABL;

      if ( ABL_CDR( Equation ) == (ablexpr *)0 )
      {
        delablexpr( Equation );
        StackArray[ ScanBit ].ABL = createablatomzero();
      }
      else
      if ( ABL_CDDR( Equation ) == (ablexpr *)0 )
      {
        Atom = ABL_CADR( Equation );
        ABL_CADR_L( Equation ) = (ablexpr *)0;
        freeablexpr( Equation );
        StackArray[ ScanBit ].ABL = Atom;
      }
    }
  }
  else
  {
/*
**  Push state in Stack_0 equation
*/
    for ( ScanStack  = FsmFigure->STACK;
          ScanStack != (fsmstack_list *)0;
          ScanStack  = ScanStack->NEXT )
    {
      if ( ScanStack->CTRL == FSM_CTRL_PUSH )
      {
        ReturnSyfState = FSM_SYF_STATE( ScanStack->RETURN );
        ScanBit        = ReturnSyfState->CODE->VALUE;

        StackArray[ ScanBit ].ABL = createablatom( ReturnSyfState->RETURN_NAME );
      }
    }

    for ( ScanBit = 0; ScanBit < SyfInfo->NUMBER_REG; ScanBit++ )
    {
      Equation = StackArray[ ScanBit ].ABL;

      if ( Equation == (ablexpr *)0 )
      {
        StackArray[ ScanBit ].ABL   = createablatomzero();
        StackArray[ ScanBit ].FLAGS = 1;
      }
    }
  }

  SyfInfo->STACK_MASK = StackMask;
  SyfInfo->STACK_CSTE = StackCste & StackMask;

  StackPrevArray = (syfregstack *)0;

  for ( Index = 0; Index < FsmFigure->STACK_SIZE; Index++ )
  {
    if ( Index + 1 < FsmFigure->STACK_SIZE )
    {
      StackNextArray = SyfInfo->STACK_ARRAY + ( SyfInfo->NUMBER_REG * ( Index + 1 ) );
    }

    BitMask  = 1;

    for ( ScanBit = 0; ScanBit < SyfInfo->NUMBER_REG; ScanBit++ )
    {
      if ( Encode == SYF_ENCODE_ONE_HOT )
      {
        Constant = SyfInfo->STACK_ARRAY[ ScanBit ].FLAGS;
      }
      else
      {
        Constant = ( BitMask & StackMask );
      }
/*
**  Special case for constants
*/
      if ( Constant )
      {
        StackArray[ ScanBit ].FLAGS = 1;

        if ( Encode != SYF_ENCODE_ONE_HOT )
        {
/*
**  Constant equation only for Stack_0
*/
          if ( Index == 0 )
          {
            delablexpr( StackArray[ ScanBit ].ABL );

            if ( StackCste & BitMask )
            {
              StackArray[ ScanBit ].ABL = createablatomone();
            }
            else
            {
              StackArray[ ScanBit ].ABL = createablatomzero();
            }
          }
        }
      }
      else
      {
/*
**  Generates Stack register equation
*/
        Stack = createabloper( ABL_OR );
        Atom  = createablatom( CtrlArray[ FSM_CTRL_NOP ].NAME );

        Equation = createablatom( StackArray[ ScanBit ].NAME_OUT );
        Equation = optimablbinexpr( ABL_AND, Equation, Atom );

        addablhexpr( Stack, Equation );

        Atom = createablatom( CtrlArray[ FSM_CTRL_PUSH ].NAME );

        if ( Index == 0 )
        {
          Equation = StackArray[ ScanBit ].ABL;
        }
        else
        {
          Equation = createablatom( StackPrevArray[ ScanBit ].NAME_OUT );
        }

        Equation = optimablbinexpr( ABL_AND, Equation, Atom );

        addablhexpr( Stack, Equation );

        if ( Index + 1 < FsmFigure->STACK_SIZE )
        {
          Atom = createablatom( CtrlArray[ FSM_CTRL_POP ].NAME );

          Equation = createablatom( StackNextArray[ ScanBit ].NAME_OUT );
          Equation = optimablbinexpr( ABL_AND, Equation, Atom );

          addablhexpr( Stack, Equation );
        }

        StackArray[ ScanBit ].ABL = Stack;
      }

      BitMask = BitMask << 1;
    }

    StackPrevArray = StackArray;
    StackArray     = StackNextArray;
  }

  if ( SyfInfo->SCAN_PATH )
  {
    StackArray = SyfInfo->STACK_ARRAY;
    PrevStack  = SyfInfo->SCAN_IN;

    for ( Index = 0; Index < SyfInfo->NUMBER_STACK; Index++ )
    {
      if ( ! StackArray[ Index ].FLAGS )
      {
        ScanPath = optimablbinexpr( ABL_AND,
                                  createablatom( PrevStack ),
                                  createablatom( SyfInfo->SCAN_TEST ) );

        Equation = optimablbinexpr( ABL_AND,
                                  StackArray[ Index ].ABL,
                                  optimablnotexpr( createablatom( SyfInfo->SCAN_TEST ) ) );

        StackArray[ Index ].ABL = optimablbinexpr( ABL_OR, Equation, ScanPath );

        PrevStack = StackArray[ Index ].NAME_OUT;
      }
    }

    SyfInfo->SCAN_STACK = PrevStack;
  }
}

/*------------------------------------------------------------\
|                                                             |
|                   SyfSynthFreeStackAbl                      |
|                                                             |
\------------------------------------------------------------*/

void SyfSynthFreeStackAbl( FsmFigure )

  fsmfig_list *FsmFigure;
{
  syfinfo       *SyfInfo;
  syfregstack   *StackArray;
  syfstate      *ReturnSyfState;
  fsmstack_list *ScanStack;
  long           Index;

  SyfInfo = FSM_SYF_INFO( FsmFigure );

  if ( SyfInfo->STACK )
  {
    StackArray = SyfInfo->STACK_ARRAY;

    for ( Index = 0; Index < SyfInfo->NUMBER_STACK; Index++ )
    {
      StackArray[ Index ].FLAGS = 0;

      if ( StackArray[ Index ].ABL != (ablexpr *)0 )
      {
        delablexpr( StackArray[ Index ].ABL );
        StackArray[ Index ].ABL = (ablexpr *)0;
      }
    }

    for ( ScanStack  = FsmFigure->STACK;
          ScanStack != (fsmstack_list *)0;
          ScanStack  = ScanStack->NEXT )
    {
      if ( ScanStack->CTRL == FSM_CTRL_PUSH )
      {
        ReturnSyfState = FSM_SYF_STATE( ScanStack->RETURN  );

        if ( ReturnSyfState->ABL_RETURN != (ablexpr *)0 )
        {
          delablexpr( ReturnSyfState->ABL_RETURN );
          ReturnSyfState->ABL_RETURN = (ablexpr *)0;
        }
      }
    }
  }
}
  
/*------------------------------------------------------------\
|                                                             |
|                      SyfSynthCtrl2Abl                       |
|                                                             |
\------------------------------------------------------------*/

void SyfSynthCtrl2Abl( FsmFigure )

  fsmfig_list *FsmFigure;
{
  fsmstack_list *ScanStack;
  syfstate      *ScanSyfState;
  syfinfo       *SyfInfo;
  syfctrl       *CtrlArray;
  ablexpr    *Equation;
  ablexpr    *CtrlNop;
  ablexpr    *Atom;
  long           Index;

  SyfInfo   = FSM_SYF_INFO( FsmFigure );
  CtrlArray = SyfInfo->CTRL_ARRAY;

  if ( ! SyfInfo->STACK ) return;

  for ( Index = 0; Index < SyfInfo->NUMBER_CTRL; Index++ )
  {
    if ( Index != FSM_CTRL_NOP )
    {
      CtrlArray[ Index ].ABL = createabloper( ABL_OR );
    }
  }

  for ( ScanStack  = FsmFigure->STACK;
        ScanStack != (fsmstack_list *)0;
        ScanStack  = ScanStack->NEXT )
  {
    if ( ScanStack->CTRL != FSM_CTRL_NOP )
    {
      if ( IsFsmStarStack( ScanStack ) )
      {
        Equation = dupablexpr( ScanStack->ABL );
      }
      else
      {
        if ( ScanStack->CTRL == FSM_CTRL_PUSH )
        {
          ScanSyfState = FSM_SYF_STATE( ScanStack->RETURN );
          Equation = createablatom( ScanSyfState->RETURN_NAME );
        }
        else
        {
          ScanSyfState = FSM_SYF_STATE( ScanStack->CURRENT );
          Atom = createablatom( ScanSyfState->CURRENT_NAME );

          Equation = optimablbinexpr( ABL_AND, 
                                       dupablexpr( ScanStack->ABL ),
                                       Atom );
        }
      }

      addablhexpr( CtrlArray[ (int)ScanStack->CTRL ].ABL, Equation );
    }
  }

  CtrlNop = createabloper( ABL_OR );

  for ( Index = 0; Index < SyfInfo->NUMBER_CTRL; Index++ )
  {
    if ( Index != FSM_CTRL_NOP )
    {
      Equation = CtrlArray[ Index ].ABL;

      if ( ABL_CDR( Equation ) == (ablexpr *)0 )
      {
        Atom = createablatomzero();
        delablexpr( Equation );
        CtrlArray[ Index ].ABL = Atom;
      }
      else
      if ( ABL_CDDR( Equation ) == (ablexpr *)0 )
      {
        Atom = ABL_CADR( Equation );
        ABL_CADR_L( Equation ) = (ablexpr *)0;
        freeablexpr( Equation );
        CtrlArray[ Index ].ABL = Atom;
      }
     
      Atom = createablatom( CtrlArray[ Index ].NAME );

      addablhexpr( CtrlNop, Atom );
    }
  }

  CtrlArray[ FSM_CTRL_NOP ].ABL = optimablnotexpr( CtrlNop );
}

/*------------------------------------------------------------\
|                                                             |
|                      SyfSynthFreeCtrlAbl                    |
|                                                             |
\------------------------------------------------------------*/

void SyfSynthFreeCtrlAbl( FsmFigure )

  fsmfig_list *FsmFigure;
{
  syfinfo       *SyfInfo;
  syfctrl       *CtrlArray;
  long           Index;

  SyfInfo   = FSM_SYF_INFO( FsmFigure );
  CtrlArray = SyfInfo->CTRL_ARRAY;

  if ( SyfInfo->STACK )
  {
    for ( Index = 0; Index < SyfInfo->NUMBER_CTRL; Index++ )
    {
      if ( CtrlArray[ Index ].ABL != (ablexpr *)0 )
      {
        delablexpr( CtrlArray[ Index ].ABL );
        CtrlArray[ Index ].ABL = (ablexpr *)0;
      }
    }
  }
}

/*------------------------------------------------------------\
|                                                             |
|                       SyfSynthOut2Abl                       |
|                                                             |
\------------------------------------------------------------*/

void SyfSynthOut2Abl( FsmFigure )

  fsmfig_list *FsmFigure;
{
  syfinfo        *SyfInfo;
  syfregout      *OutArray;
  fsmout_list    *ScanOutput;
  fsmout_list    *ScanOut;
  fsmstate_list  *ScanState;
  fsmlocout_list *ScanLocout;
  syfout         *ScanSyfOut;
  syfstate       *ScanSyfState;
  ablexpr        *Equation = NULL;
  ablexpr        *ScanPath;
  ablexpr        *Atom;
  char           *PrevScan;
  long            Index;

  SyfInfo  = FSM_SYF_INFO( FsmFigure );
  OutArray = SyfInfo->OUT_ARRAY;
  ScanOut  = (fsmout_list *)0;

  for ( ScanOutput  = FsmFigure->OUT;
        ScanOutput != (fsmout_list *)0;
        ScanOutput  = ScanOutput->NEXT )
  {
    ScanSyfOut = FSM_SYF_OUT( ScanOutput );

    if ( SyfInfo->SCAN_OUT == ScanOutput->NAME )
    {
      ScanOut = ScanOutput;
    }

    ScanSyfOut->ABL = createabloper( ABL_OR );
  }

  for ( ScanState  = FsmFigure->STATE;
        ScanState != (fsmstate_list *)0;
        ScanState  = ScanState->NEXT )
  {
    ScanSyfState = FSM_SYF_STATE( ScanState );
  //ScanSyfCode  = ScanSyfState->CODE;

    for ( ScanLocout  = ScanState->LOCOUT;
          ScanLocout != (fsmlocout_list *)0;
          ScanLocout  = ScanLocout->NEXT )
    {
      ScanSyfOut = FSM_SYF_OUT( ScanLocout->OUT );

      if ( SyfInfo->REG_OUT )
      {
        if ( SyfInfo->STACK )
        {
          Atom = createablatom( ScanSyfState->NEXT_IN_NAME );
        }
        else
        {
          Atom = createablatom( ScanSyfState->NEXT_NAME );
        }
      }
      else
      {
        Atom = createablatom( ScanSyfState->CURRENT_NAME );
      }

      if ( ScanLocout->ABL_DC != (ablexpr *)0 )
      {
        Equation = optimablbinexpr( ABL_AND, 
                                     dupablexpr( ScanLocout->ABL_DC ),
                                     createablatom( ABL_ATOM_NAME_DC ) );
      }

      if ( ScanLocout->ABL != (ablexpr *)0 )
      {
        if ( ScanLocout->ABL_DC != (ablexpr *)0 )
        {
          Equation = optimablbinexpr( ABL_OR, 
                                       dupablexpr( ScanLocout->ABL ),
                                       Equation );
        }
        else
        {
          Equation = dupablexpr( ScanLocout->ABL );
        }
      }

      Equation = optimablbinexpr( ABL_AND, Atom, Equation );

      addablhexpr( ScanSyfOut->ABL, Equation );
    }
  }

  ScanState = FsmFigure->STAR_STATE;

  if ( ScanState != (fsmstate_list *)0 )
  {
    for ( ScanLocout  = ScanState->LOCOUT;
          ScanLocout != (fsmlocout_list *)0;
          ScanLocout  = ScanLocout->NEXT )
    {
      ScanSyfOut = FSM_SYF_OUT( ScanLocout->OUT );

      if ( ScanLocout->ABL_DC != (ablexpr *)0 )
      {
        Equation = optimablbinexpr( ABL_AND, 
                                     dupablexpr( ScanLocout->ABL_DC ),
                                     createablatom( ABL_ATOM_NAME_DC ) );
      }

      if ( ScanLocout->ABL != (ablexpr *)0 )
      {
        if ( ScanLocout->ABL_DC != (ablexpr *)0 )
        {
          Equation = optimablbinexpr( ABL_OR, 
                                       dupablexpr( ScanLocout->ABL ),
                                       Equation );
        }
        else
        {
          Equation = dupablexpr( ScanLocout->ABL );
        }
      }

      addablhexpr( ScanSyfOut->ABL, Equation );
    }
  }
 
  for ( ScanOutput  = FsmFigure->OUT;
        ScanOutput != (fsmout_list *)0;
        ScanOutput  = ScanOutput->NEXT )
  {
    ScanSyfOut = FSM_SYF_OUT( ScanOutput );

    Equation = ScanSyfOut->ABL;

    if ( ABL_CDR( Equation ) == (ablexpr *)0 )
    {
/*
**  Out(i) = OR Null -> Out(i) = 0
*/
      if ( ScanOutput != ScanOut )
      {
        Atom = createablatomzero();
      }
      else
      {
        Atom = createablatom( SyfInfo->SCAN_IN );
      }

      delablexpr( Equation );
      ScanSyfOut->ABL = Atom;
    }
    else
    if ( ABL_CDDR( Equation ) == (ablexpr *)0 )
    {
/*
**  Out(i) = OR Locout(j) -> Out(i) = Locout(j)
*/
      Atom = ABL_CADR( Equation );
      ABL_CADR_L( Equation ) = (ablexpr *)0;
      freeablexpr( Equation );
      ScanSyfOut->ABL = Atom;
    }
  }

  if ( SyfInfo->REG_OUT )
  {
    Index = 0;

    for ( ScanOutput  = FsmFigure->OUT;
          ScanOutput != (fsmout_list *)0;
          ScanOutput  = ScanOutput->NEXT )
    {
      if ( ScanOutput != ScanOut )
      {
        ScanSyfOut = FSM_SYF_OUT( ScanOutput );

        if ( ! ABL_ATOM( ScanSyfOut->ABL ) )
        {
          OutArray[ Index ].ABL = ScanSyfOut->ABL;
          ScanSyfOut->ABL = createablatom( OutArray[ Index ].NAME_OUT );
        }

        Index = Index + 1;
      }
    }
  }

  if ( SyfInfo->SCAN_PATH )
  {
    PrevScan = SyfInfo->REG_ARRAY[ SyfInfo->NUMBER_REG - 1 ].NAME_OUT;

    if ( SyfInfo->REG_OUT )
    {
      for ( Index = 0; Index < SyfInfo->NUMBER_OUT; Index++ )
      {
        if ( OutArray[ Index ].ABL == (ablexpr *)0 ) continue;
          
        ScanPath = optimablbinexpr( ABL_AND, 
                                     createablatom( PrevScan ),
                                     createablatom( SyfInfo->SCAN_TEST ) );

        Equation = optimablbinexpr( ABL_AND,
                                     OutArray[ Index ].ABL,
                                     optimablnotexpr( createablatom( SyfInfo->SCAN_TEST ) ) );

        OutArray[ Index ].ABL = optimablbinexpr( ABL_OR, Equation, ScanPath );

        PrevScan = OutArray[ Index ].NAME_OUT;
      }
    }

    ScanSyfOut = FSM_SYF_OUT( ScanOut );
    ScanSyfOut->ABL = createablatom( PrevScan );
  }
}

/*------------------------------------------------------------\
|                                                             |
|                    SyfSynthFreeOutAbl                       |
|                                                             |
\------------------------------------------------------------*/

void SyfSynthFreeOutAbl( FsmFigure )

  fsmfig_list *FsmFigure;
{
  syfinfo        *SyfInfo;
  syfregout      *OutArray;
  fsmout_list    *ScanOutput;
  syfout         *ScanSyfOut;
  long            Index;

  SyfInfo = FSM_SYF_INFO( FsmFigure );

  for ( ScanOutput  = FsmFigure->OUT;
        ScanOutput != (fsmout_list *)0;
        ScanOutput  = ScanOutput->NEXT )
  {
    ScanSyfOut = FSM_SYF_OUT( ScanOutput );

    if ( ScanSyfOut->ABL != (ablexpr *)0 )
    {
      delablexpr( ScanSyfOut->ABL );
      ScanSyfOut->ABL = (ablexpr *)0;
    }
  }

  if ( SyfInfo->REG_OUT )
  {
    OutArray = SyfInfo->OUT_ARRAY;

    for ( Index = 0; Index < SyfInfo->NUMBER_OUT; Index++ )
    {
      if ( OutArray[ Index ].ABL != (ablexpr *)0 )
      {
        delablexpr( OutArray[ Index ].ABL );
        OutArray[ Index ].ABL = (ablexpr *)0;
      }
    }
  }
}

/*------------------------------------------------------------\
|                                                             |
|                       SyfSynthReg2Abl                       |
|                                                             |
\------------------------------------------------------------*/

void SyfSynthReg2Abl( FsmFigure )

  fsmfig_list *FsmFigure;
{
  syfinfo       *SyfInfo;
  fsmstate_list *ScanState;
  fsmstate_list *StarState;
  fsmtrans_list *StarTrans;
  chain_list    *ScanChain;
  ablexpr       *Equation;
  ablexpr       *ScanPath;
  ablexpr       *Stack;
  ablexpr       *Atom;
  ablexpr       *AblReset;
  ablexpr       *AblSet;
  syfstate      *ScanSyfState;
  syfcode       *ScanCode;
  syfregstate   *RegArray;
  syfctrl       *CtrlArray;
  syfregstack   *StackArray;
  char          *PrevScan;
  long           Index;
  long           BitMask;
  long           ScanBit;
  char           Encode;

  SyfInfo    = FSM_SYF_INFO( FsmFigure );
  RegArray   = SyfInfo->REG_ARRAY;
  StackArray = SyfInfo->STACK_ARRAY;
  CtrlArray  = SyfInfo->CTRL_ARRAY;
  Encode     = SyfInfo->ENCODE;

  for ( Index = 0; Index < SyfInfo->NUMBER_REG; Index++ )
  {
    RegArray[ Index ].ABL       = createabloper( ABL_OR );
    RegArray[ Index ].ABL_SET   = createabloper( ABL_OR );
    RegArray[ Index ].ABL_RESET = createabloper( ABL_OR );
  }

/*
**  If Code[i] of E(j), Reg(i) <- Reg(i) OR E(j)
*/
  for ( ScanState  = FsmFigure->STATE;
        ScanState != (fsmstate_list *)0;
        ScanState  = ScanState->NEXT )
  {
    ScanSyfState = FSM_SYF_STATE( ScanState );
    ScanCode     = ScanSyfState->CODE;

    if ( Encode == SYF_ENCODE_ONE_HOT )
    {
      Atom = createablatom( ScanSyfState->NEXT_NAME );

      addablhexpr( RegArray[ ScanCode->VALUE ].ABL, Atom );
    }
    else
    {
      BitMask = 1;

      for ( ScanBit = 0; ScanBit < SyfInfo->NUMBER_REG; ScanBit++ )
      {
        if ( ScanCode->VALUE & BitMask )
        {
          Atom = createablatom( ScanSyfState->NEXT_NAME );

          addablhexpr( RegArray[ ScanBit ].ABL, Atom );
        }

        BitMask = BitMask << 1;
      }
    }
  }

  for ( Index = 0; Index < SyfInfo->NUMBER_REG; Index++ )
  {
    Equation = RegArray[ Index ].ABL;

    if ( ABL_CDR( Equation ) == (ablexpr *)0 )
    {
/*
**  Reg(i) = OR Null -> Reg(i) = 0
*/
      Atom = createablatomzero();
      delablexpr( Equation );
      RegArray[ Index ].ABL = Atom;
    }
    else
    if ( ABL_CDDR( Equation ) == (ablexpr *)0 )
    {
/*
**  Reg(i) = OR E(j) -> Reg(i) = E(j)
*/
      Atom = ABL_CADR( Equation );
      ABL_CADR_L( Equation ) = (ablexpr *)0;
      freeablexpr( Equation );
      RegArray[ Index ].ABL = Atom;
    }

    if ( SyfInfo->STACK )
    {
      Atom = createablatom( CtrlArray[ FSM_CTRL_POP ].NAME );

      Equation = createablatom( StackArray[ Index ].NAME_OUT );
      Stack = optimablbinexpr( ABL_AND, Equation, dupablexpr( Atom ) );

      Equation = optimablbinexpr( ABL_AND,
                                   RegArray[ Index ].ABL, 
                                   optimablnotexpr( Atom ) );

      RegArray[ Index ].ABL = optimablbinexpr( ABL_OR, Stack, Equation );
    }
  }
/*
** Compute the Set and Reset conditions
*/
  StarState = FsmFigure->STAR_STATE;

  if ( StarState != (fsmstate_list *)0 )
  {
    for ( ScanChain  = StarState->FROM;
          ScanChain != (chain_list *)0;
          ScanChain  = ScanChain->NEXT )
    {
      StarTrans = (fsmtrans_list *)ScanChain->DATA;
      ScanState = StarTrans->TO;

      ScanSyfState = FSM_SYF_STATE( ScanState );
      ScanCode     = ScanSyfState->CODE;

      if ( Encode == SYF_ENCODE_ONE_HOT )
      {
        Atom = createablatom( ScanSyfState->NEXT_NAME );

        addablhexpr( RegArray[ ScanCode->VALUE ].ABL_SET, dupablexpr( StarTrans->ABL ) );

        for ( ScanBit = 0; ScanBit < SyfInfo->NUMBER_REG; ScanBit++ )
        {
          if ( ScanBit == ScanCode->VALUE ) continue;

          addablhexpr( RegArray[ ScanBit ].ABL_RESET, dupablexpr( StarTrans->ABL ) );
        }
      }
      else
      {
        BitMask = 1;

        for ( ScanBit = 0; ScanBit < SyfInfo->NUMBER_REG; ScanBit++ )
        {
          if ( ScanCode->VALUE & BitMask )
          {
            addablhexpr( RegArray[ ScanBit ].ABL_SET, dupablexpr( StarTrans->ABL ) );
          }
          else
          {
            addablhexpr( RegArray[ ScanBit ].ABL_RESET, dupablexpr( StarTrans->ABL ) );
          }

          BitMask = BitMask << 1;
        }
      }
    }
  }

/*
** Add Reset and Set conditions
*/
  for ( Index = 0; Index < SyfInfo->NUMBER_REG; Index++ )
  {
    Equation = RegArray[ Index ].ABL_SET;

    if ( ABL_CDR( Equation ) == (ablexpr *)0 )
    {
      freeablexpr( Equation );
      RegArray[ Index ].ABL_SET = (chain_list *)0;
    }
    else
    if ( ABL_CDDR( Equation ) == (ablexpr *)0 )
    {
      Atom = ABL_CADR( Equation );
      ABL_CADR_L( Equation ) = (ablexpr *)0;
      freeablexpr( Equation );
      RegArray[ Index ].ABL_SET = Atom;
    }

    Equation = RegArray[ Index ].ABL_RESET;

    if ( ABL_CDR( Equation ) == (ablexpr *)0 )
    {
      freeablexpr( Equation );
      RegArray[ Index ].ABL_RESET = (chain_list *)0;
    }
    else
    if ( ABL_CDDR( Equation ) == (ablexpr *)0 )
    {
      Atom = ABL_CADR( Equation );
      ABL_CADR_L( Equation ) = (ablexpr *)0;
      freeablexpr( Equation );
      RegArray[ Index ].ABL_RESET = Atom;
    }
  }

  for ( Index = 0; Index < SyfInfo->NUMBER_REG; Index++ )
  {
    AblSet   = RegArray[ Index ].ABL_SET;
    AblReset = RegArray[ Index ].ABL_RESET;

    RegArray[ Index ].ABL_SET   = (ablexpr *)0;
    RegArray[ Index ].ABL_RESET = (ablexpr *)0;

    Equation = createablatom( RegArray[ Index ].NAME_IN );

    if ( AblReset != (ablexpr *)0 )
    {
      AblReset = optimablnotexpr( AblReset );
      Equation = optimablbinexpr( ABL_AND, Equation, AblReset );
    }

    if ( AblSet != (ablexpr *)0 )
    {
      Equation = optimablbinexpr( ABL_OR, Equation, AblSet );
    }

    RegArray[ Index ].ABL_IN = Equation;
  }
/*
** Add a scan path
*/
  if ( SyfInfo->SCAN_PATH )
  {
    if ( SyfInfo->STACK )
    {
      PrevScan = SyfInfo->SCAN_STACK;
    }
    else
    {
      PrevScan = SyfInfo->SCAN_IN;
    }

    for ( Index = 0; Index < SyfInfo->NUMBER_REG; Index++ )
    {
      ScanPath = optimablbinexpr( ABL_AND, 
                                  createablatom( PrevScan ),
                                  createablatom( SyfInfo->SCAN_TEST ) );

      Equation = optimablbinexpr( ABL_AND,
                                  RegArray[ Index ].ABL_IN,
                                  optimablnotexpr( createablatom( SyfInfo->SCAN_TEST ) ) );

      RegArray[ Index ].ABL_IN = optimablbinexpr( ABL_OR, Equation, ScanPath );

      PrevScan = RegArray[ Index ].NAME_OUT;
    }
  }
}

/*------------------------------------------------------------\
|                                                             |
|                   SyfSynthFreeRegAbl                        |
|                                                             |
\------------------------------------------------------------*/

void SyfSynthFreeRegAbl( FsmFigure )

  fsmfig_list *FsmFigure;
{
  syfinfo     *SyfInfo;
  syfregstate *RegArray;
  long         Index;

  SyfInfo  = FSM_SYF_INFO( FsmFigure );
  RegArray = SyfInfo->REG_ARRAY;

  for ( Index = 0; Index < SyfInfo->NUMBER_REG; Index++ )
  {
    if ( RegArray[ Index ].ABL != (ablexpr *)0 )
    {
      delablexpr( RegArray[ Index ].ABL );
      RegArray[ Index ].ABL = (ablexpr *)0;
    }
  }
}

/*------------------------------------------------------------\
|                                                             |
|                     SyfSynthCode2Abl                        |
|                                                             |
\------------------------------------------------------------*/

void SyfSynthCode2Abl( FsmFigure, FlagDc )

  fsmfig_list *FsmFigure;
  int          FlagDc;
{
  syfinfo     *SyfInfo;
  syfcode     *CodeArray;
  syfregstate *RegArray;
  ablexpr     *Equation;
  ablexpr     *EquationOut = NULL;
  long         Index;
  long         BitMask;
  long         ScanBit;
  char         DecodeOut;
  char         Encode;

  SyfInfo   = FSM_SYF_INFO( FsmFigure );
  Encode    = SyfInfo->ENCODE;

  if ( ( Encode != SYF_ENCODE_ONE_HOT ) &&
       ( Encode != SYF_ENCODE_FRANCK  ) &&
       ( FlagDc                       ) )
  {
    SyfSynthCodeDc2Abl( FsmFigure ); return;
  }

  CodeArray = SyfInfo->CODE_ARRAY;
  RegArray  = SyfInfo->REG_ARRAY;
  DecodeOut = ( SyfInfo->REG_OUT ) && ( SyfInfo->STACK );

  for ( Index = 0; Index < SyfInfo->NUMBER_CODE; Index++ )
  {
    if ( Encode == SYF_ENCODE_ONE_HOT )
    {
      Equation = createablatom( RegArray[ Index ].NAME_OUT );

      if ( DecodeOut )
      {
        EquationOut = createablatom( RegArray[ Index ].NAME_IN );
      }
    }
    else
    if ( SyfInfo->NUMBER_BIT < 2 )
    {
      Equation = createablatom( RegArray[ 0 ].NAME_OUT );

      if ( DecodeOut )
      {
        EquationOut = createablatom( RegArray[ 0 ].NAME_IN );
      }

      if ( ! CodeArray[ Index ].VALUE )
      {
        Equation = optimablnotexpr( Equation );

        if ( DecodeOut )
        {
          EquationOut = optimablnotexpr( EquationOut );
        }
      }
    }
    else
    {
      Equation = createabloper( ABL_AND );
      BitMask  = 1;

      if ( DecodeOut )
      {
        EquationOut = createabloper( ABL_AND );
      }

      for ( ScanBit = 0; ScanBit < SyfInfo->NUMBER_REG; ScanBit++ )
      {
        if ( CodeArray[ Index ].VALUE & BitMask )
        {
          addablhexpr( Equation,  
                       createablatom( RegArray[ ScanBit ].NAME_OUT ) );

          if ( DecodeOut )
          {
            addablhexpr( EquationOut,
                         createablatom( RegArray[ ScanBit ].NAME_IN ) );
          }
        }
        else
        {
          addablhexpr( Equation,
                       optimablnotexpr( createablatom( RegArray[ ScanBit ].NAME_OUT ) ) );

          if ( DecodeOut )
          {
            addablhexpr( EquationOut,
                         optimablnotexpr( createablatom( RegArray[ ScanBit ].NAME_IN ) ) );

          }
        }

        BitMask = BitMask << 1;
      }
    }

    CodeArray[ Index ].ABL = Equation;

    if ( DecodeOut )
    {
      CodeArray[ Index ].ABL_OUT = EquationOut;
    }
  }
}

/*------------------------------------------------------------\
|                                                             |
|                   SyfSynthFreeCodeAbl                       |
|                                                             |
\------------------------------------------------------------*/

void SyfSynthFreeCodeAbl( FsmFigure )

  fsmfig_list *FsmFigure;
{
  syfinfo *SyfInfo;
  syfcode *CodeArray;
  long     Index;

  SyfInfo   = FSM_SYF_INFO( FsmFigure );
  CodeArray = SyfInfo->CODE_ARRAY;

  for ( Index = 0; Index < SyfInfo->NUMBER_CODE; Index++ )
  {
    if ( CodeArray[ Index ].ABL != (ablexpr *)0 )
    {
      delablexpr( CodeArray[ Index ].ABL );
      CodeArray[ Index ].ABL = (ablexpr *)0;
    }

    if ( CodeArray[ Index ].ABL_OUT != (ablexpr *)0 )
    {
      delablexpr( CodeArray[ Index ].ABL_OUT );
      CodeArray[ Index ].ABL_OUT = (ablexpr *)0;
    }
  }
}

/*------------------------------------------------------------\
|                                                             |
|                      SyfSynthTrans2Abl                      |
|                                                             |
\------------------------------------------------------------*/

void SyfSynthTrans2Abl( FsmFigure )

  fsmfig_list *FsmFigure;
{
//syfinfo       *SyfInfo;
  fsmstate_list *ScanState;
  syfstate      *ScanSyfState;
  syfstate      *FromSyfState;
  ablexpr       *ScanChain;
  ablexpr       *Atom;
  fsmtrans_list *ScanTrans;

//SyfInfo = FSM_SYF_INFO( FsmFigure );

  for ( ScanState  = FsmFigure->STATE;
        ScanState != (fsmstate_list *)0;
        ScanState  = ScanState->NEXT )
  {
    ScanChain    = ScanState->TO;
    ScanSyfState = FSM_SYF_STATE( ScanState );

    if ( ScanChain == (ablexpr *)0 )
    {
/*
**  No transition to E(i)
*/
      ScanSyfState->ABL_TRANS = createablatomzero();
    }
    else
    if ( ScanChain->NEXT == (ablexpr *)0 )
    {
/*
**  One transition to E(i)
*/
      ScanTrans    = (fsmtrans_list *)( ScanChain->DATA );

      if ( IsFsmStarTrans( ScanTrans ) )
      {
        ScanSyfState->ABL_TRANS = createablatomzero();
      }
      else
      {
        FromSyfState = FSM_SYF_STATE( ScanTrans->FROM );

        Atom = createablatom( FromSyfState->CURRENT_NAME );
      
        ScanSyfState->ABL_TRANS = 

           optimablbinexpr( ABL_AND, Atom, dupablexpr( ScanTrans->ABL ) );
      }
    }
    else
    {
/*
**  More than one transition to E(i)
*/
      ScanSyfState->ABL_TRANS = createabloper( ABL_OR );

      while ( ScanChain != (ablexpr *)0 )
      {
        ScanTrans = (fsmtrans_list *)( ScanChain->DATA );

        if ( IsFsmStarTrans( ScanTrans ) )
        {
          addablhexpr( ScanSyfState->ABL_TRANS, createablatomzero() );
        }
        else
        {
          FromSyfState = FSM_SYF_STATE( ScanTrans->FROM );

          Atom = createablatom( FromSyfState->CURRENT_NAME );
      
          addablhexpr( ScanSyfState->ABL_TRANS, 
                       optimablbinexpr( ABL_AND, 
                                         Atom, dupablexpr( ScanTrans->ABL ) ) );

        }

        ScanChain = ScanChain->NEXT;
      }
    }
  }
}

/*------------------------------------------------------------\
|                                                             |
|                      SyfSynthFreeTransAbl                   |
|                                                             |
\------------------------------------------------------------*/

void SyfSynthFreeTransAbl( FsmFigure )

  fsmfig_list *FsmFigure;
{
  fsmstate_list *ScanState;
  syfstate      *ScanSyfState;

  for ( ScanState  = FsmFigure->STATE;
        ScanState != (fsmstate_list *)0;
        ScanState  = ScanState->NEXT )
  {
    ScanSyfState = FSM_SYF_STATE( ScanState );

    if ( ScanSyfState->ABL_TRANS != (ablexpr *)0 )
    {
      delablexpr( ScanSyfState->ABL_TRANS );
      ScanSyfState->ABL_TRANS = (ablexpr *)0;
    }
  }
}

/*------------------------------------------------------------\
|                                                             |
|                       SyfSynthFsm2Abl                       |
|                                                             |
\------------------------------------------------------------*/

void SyfSynthFsm2Abl( FsmFigure )

  fsmfig_list *FsmFigure;
{
//syfinfo *SyfInfo;
  
//SyfInfo = FSM_SYF_INFO( FsmFigure );

  SyfSynthTrans2Abl( FsmFigure );
  SyfSynthReturn2Abl( FsmFigure );
  SyfSynthOut2Abl( FsmFigure );
  SyfSynthCtrl2Abl( FsmFigure );
  SyfSynthStack2Abl( FsmFigure );
  SyfSynthReg2Abl( FsmFigure );
}

/*------------------------------------------------------------\
|                                                             |
|                      SyfSynthFreeFsmAbl                     |
|                                                             |
\------------------------------------------------------------*/

void SyfSynthFreeFsmAbl( FsmFigure )

  fsmfig_list *FsmFigure;
{
  SyfSynthFreeTransAbl( FsmFigure );
  SyfSynthFreeReturnAbl( FsmFigure );
  SyfSynthFreeOutAbl( FsmFigure );
  SyfSynthFreeCtrlAbl( FsmFigure );
  SyfSynthFreeStackAbl( FsmFigure );
  SyfSynthFreeRegAbl( FsmFigure );
}

/*------------------------------------------------------------\
|                                                             |
|                      SyfSynthFsmInit                        |
|                                                             |
\------------------------------------------------------------*/

void SyfSynthFsmInit( FsmFigure )

  fsmfig_list *FsmFigure;
{
  syfinfo     *SyfInfo;
  char         Buffer[ 25 ];
  syfregstate *RegArray;
  long         RegMax;
  syfregout   *OutArray;
  long         OutMax;
  syfregstack *StackArray;
  long         StackMax;
  syfctrl     *CtrlArray;
  long         CtrlMax;
  long         Index;
  long         Stack;
  long         ScanBit;

  SyfInfo = FSM_SYF_INFO( FsmFigure );

  RegMax   = SyfInfo->NUMBER_BIT;
  RegArray = (syfregstate  *)autallocblock( sizeof( syfregstate ) * RegMax );

  for ( Index = 0; Index < RegMax; Index++ )
  {
    sprintf( Buffer, "%s_%s %ld", FsmFigure->NAME, SyfInfo->CURRENT_STATE, Index );
    RegArray[ Index ].NAME_OUT = namealloc( Buffer );
    sprintf( Buffer, "%s_%s %ld", FsmFigure->NAME, SyfInfo->NEXT_STATE, Index );
    RegArray[ Index ].NAME_IN = namealloc( Buffer );
    RegArray[ Index ].NAME_MASTER = RegArray[ Index ].NAME_OUT;
  }

  SyfInfo->REG_ARRAY  = RegArray;
  SyfInfo->NUMBER_REG = RegMax;

  if ( SyfInfo->REG_OUT )
  {
    if ( SyfInfo->SCAN_PATH )
    {
      OutMax = FsmFigure->NUMBER_OUT - 1;
    }
    else
    {
      OutMax = FsmFigure->NUMBER_OUT;
    }

    OutArray = (syfregout *)autallocblock( sizeof( syfregout ) * OutMax );

    for ( Index = 0; Index < OutMax; Index++ )
    {
      sprintf( Buffer, "%s_regouts_%ld", FsmFigure->NAME, Index );
      OutArray[ Index ].NAME_OUT = namealloc( Buffer );
      OutArray[ Index ].NAME_MASTER = OutArray[ Index ].NAME_OUT;
    }

    SyfInfo->OUT_ARRAY  = OutArray;
    SyfInfo->NUMBER_OUT = OutMax;
  }

  if ( SyfInfo->STACK )
  {
    CtrlMax    = FSM_MAX_CTRL;
    StackMax   = FsmFigure->STACK_SIZE * SyfInfo->NUMBER_REG;
    CtrlArray  = (syfctrl *)autallocblock( sizeof( syfctrl ) * CtrlMax );
    StackArray = (syfregstack *)autallocblock( sizeof( syfregstack ) * StackMax );

    for ( Index = 0; Index < CtrlMax; Index++ )
    {
      sprintf( Buffer, "%s_ctrl_%s", FsmFigure->NAME, FSM_CTRL_NAME[ Index ] );
      CtrlArray[ Index ].NAME = namealloc( Buffer );
    }

    SyfInfo->NUMBER_CTRL = CtrlMax;
    SyfInfo->CTRL_ARRAY  = CtrlArray;

    Index = 0;

    for ( Stack = 0; Stack < FsmFigure->STACK_SIZE; Stack++ )
    {
      for ( ScanBit = 0; ScanBit < SyfInfo->NUMBER_REG; ScanBit++ )
      {
        sprintf( Buffer, "%s_stacks_%ld_%ld", FsmFigure->NAME, Stack, ScanBit );
        StackArray[ Index ].NAME_OUT = namealloc( Buffer );
        StackArray[ Index ].NAME_MASTER = StackArray[ Index ].NAME_OUT;

        Index = Index + 1;
      }
    }

    SyfInfo->NUMBER_STACK = StackMax;
    SyfInfo->STACK_ARRAY  = StackArray;
  }
}
