Provided by: alliance_5.0-20110203-4_i386 bug

NAME

       fsm - Alliance VHDL Finite State Machine description subset.

DESCRIPTION

       This  document  describes  the  Alliance  VHDL  subset for Finite State
       Machine description.

       This FSM subset is neither accepted by the logic  simulator  asimut(1),
       nor the formal prover proof(1).

       This  VHDL  subset  is  defined  to  enable  classical MOORE and MEALEY
       synchronous finite state machine  description  as  well  as  stack  FSM
       description  (see  syf(1)  for  further  information about this kind of
       FSM).
       A FSM description is made of two and only  two  processes.   Connectors
       and  signals  can  only  be of in, out, and two user defined enumerated
       types.  Vectors of in and out types are also allowed.
       FSM's states and stack control signals must be declared  as  enumerated
       type.
       For the scan-path, three more signals are required :
              - scan_test: in bit
              - scan_in: in bit
              - scan_out: out bit
       For  a  ROM implementation, the vdd and vss signals must be explicitely
       declared as :
              - rom_vdd : in bit
              - rom_vss : in bit

These signals, declared in the interface, are not used or assigned in the FSM

       description.
       The '-P' option of syf(1) allows scan-path implementation.

       Pragmas :
              A  pragma  is a comment that gives necessary informations to the
              synthesis and formal proof tools.

              Three pragmas are used, their generic names are :
                     - CLOCK : External clock signal name.
                     - CURRENT_STATE : Current State name.
                     - NEXT_STATE : Next State name.

Ten other pragmas are optional.

       Three pragmas are required only for scan-path implementation.
              - SCAN_TEST : Enable test mode (scan-path).
              - SCAN_IN : scan-path input.
              - SCAN_OUT : scan-path output.

Five others are used only in a STACK FSM.

              - RETURN_STATE : Return State name.
              - CONTROL : Stack Control signal name.
              - POP : POP operation on the stack.
              - PUSH : PUSH operation on the stack.
              - NOP : NOP operation on the stack.

The last ones for ROM implementation

              - ROM_VDD : Name of the vdd signal of the ROM.
              - ROM_VSS :Name of the vss signal of the ROM.

       Two different processes are used :  The  first  process,  called  state
       process,
       allows  to describe state transition and outputs generation.  It is not
       controlled by the clock.  The second process is controlled by the clock
       and descibes the state register and stack registers modifications.
       State  process  sensitivity  list contains inputs and CURRENT_STATE, it
       means that the state process is activated when the CURRENT_STATE or  an
       input  signal  changes.  A case statement is used to describe, for each
       state, the next state and outputs.
       The second process sensitivity list contains the clock signal, so  this
       process  is  enabled  whenever  clock  changes.   Both  Level sensitive
       latches, and edge triggered flip flops can be used for state  registers
       and stack implementation.

EXAMPLE

       Entity FSM_EX is

       port(
          ck    : in bit ;
          reset :in bit;
          t_mode:in bit;
          s_in  :in bit;
          i     :in bit;
          s_out :out bit;
          o     :out bit
       );
       End FSM_EX;

       architecture auto of FSM_EX is

       type STATE_TYPE is (S0,S1,S2,S3,S4,S5);
       type CONTROL is (PUSH,POP,NOP);

       -- pragma CLOCK ck
       -- pragma CURRENT_STATE CURRENT_STATE
       -- pragma NEXT_STATE NEXT_STATE
       -- pragma RETURN_STATE RETURN_STATE
       -- pragma CONTROL CTRL
       -- pragma PUSH PUSH
       -- pragma POP POP
       -- pragma NOP NOP
       -- pragma SCAN_TEST t_mode
       -- pragma SCAN_IN s_in
       -- pragma SCAN_OUT s_out

       signal CURRENT_STATE, NEXT_STATE, RETURN_STATE : STATE_TYPE;
       signal CTRL : CONTROL;
       signal STACK_0, STACK_1 : STATE_TYPE ;

       begin

       PROCESS(CURRENT_STATE,I,reset)
         begin
           if(reset) then
             NEXT_STATE <= S0 ;
             o <= '0' ;
         else
             case CURRENT_STATE is
               WHEN S0 =>
               NEXT_STATE <= S1;
               RETURN_STATE <= S5;
               CTRL <= PUSH;

               o <= '0';

               WHEN S1 =>
               if (I = '1') then
                 NEXT_STATE <= S2;
                 CTRL <= NOP;
               else
                 NEXT_STATE <= S3;
                 CTRL <= NOP;
               end if;

               o <= '0';

               WHEN S2 =>
               NEXT_STATE <= S4;
               CTRL <= NOP;

               o <= '0';

               WHEN S3 =>
               NEXT_STATE <= S4;
               CTRL <= NOP;

               o <= '0';

               WHEN S4 =>
               NEXT_STATE <= STACK_0;
               CTRL <= POP;

               o <= '1';

               WHEN S5 =>
               if (I = '1') then
                 NEXT_STATE <= S1;
                 RETURN_STATE <= S0 ;
                 CTRL <= PUSH;
               else
                 NEXT_STATE <= S5;
                 CTRL <= NOP;
               end if ;

               o <= '0';

              WHEN others =>
               assert ('1')
               report "illegal state";

           end case;
         end if ;
       end process;

       process(ck)
         begin
           if(ck = '0' and not ck' stable) then
             CURRENT_STATE <= NEXT_STATE;
             case CTRL is
               WHEN POP =>
                 STACK_0 <= STACK_1;

               WHEN PUSH =>
                 STACK_1 <= STACK_0;
                 STACK_0 <= RETURN_STATE;
               WHEN NOP =>
                 NULL;
             end case;
           end if;
       end process;

       end auto;

MULTI FSM EXAMPLE

       It  is  possible  to  describe  in the same description two or more FSM
       communicating each others throw internal signals as shown  bellow.   It
       is also possible to incorporate concurrent statements using VBE(5) VHDL
       coding style.

       ENTITY multi_fsm is
       PORT
       ( ck       : in  BIT;
         data_in  : in  BIT;
         reset    : in  BIT;
         data_out : out BIT
       );
       END multi_fsm;

       ARCHITECTURE FSM OF multi_fsm is

          TYPE A_ETAT_TYPE IS (A_E0, A_E1);
          SIGNAL A_NS, A_CS : A_ETAT_TYPE;

          TYPE B_ETAT_TYPE IS (B_E0, B_E1);
          SIGNAL B_NS, B_CS : B_ETAT_TYPE;

       --PRAGMA CURRENT_STATE A_CS  FSM_A
       --PRAGMA NEXT_STATE A_NS     FSM_A
       --PRAGMA CLOCK ck            FSM_A
       --PRAGMA FIRST_STATE A_E0    FSM_A

       --PRAGMA CURRENT_STATE B_CS  FSM_B
       --PRAGMA NEXT_STATE B_NS     FSM_B
       --PRAGMA CLOCK ck            FSM_B
       --PRAGMA FIRST_STATE B_E0    FSM_B

          SIGNAL ACK, REQ, DATA_INT : BIT;

       BEGIN

       A_1 : PROCESS ( A_CS, ACK )
       BEGIN
         IF ( reset = '1' )
         THEN A_NS     <= A_E0;
              DATA_OUT <= '0';
              REQ      <= '0';
         ELSE
         CASE A_CS is
           WHEN A_E0 =>
             IF ( ACK ='1') THEN A_NS <= A_E1;
                            ELSE A_NS <= A_E0;
             END IF;
             DATA_OUT <= '0';
             REQ      <= '1';
           WHEN A_E1 =>
             IF ( ACK ='1') THEN A_NS <= A_E1;
                            ELSE A_NS <= A_E0;
             END IF;
             DATA_OUT <= DATA_INT;
             REQ      <= '0';
         END CASE;
         END IF;
       END PROCESS A_1;

       A_2 : PROCESS( ck )
       BEGIN
           IF ( ck = '1' AND NOT ck'STABLE )
           THEN A_CS <= A_NS;
           END IF;
       END PROCESS A_2;

       -------

       B_1 : PROCESS ( B_CS, ACK )
       BEGIN
         IF ( reset = '1' )
         THEN B_NS     <= B_E0;
              DATA_INT <= '0';
              ACK      <= '0';
         ELSE
         CASE B_CS is
           WHEN B_E0 =>
             IF ( REQ ='1') THEN B_NS <= B_E1;
                            ELSE B_NS <= B_E0;
             END IF;
             DATA_INT <= '0';
             ACK      <= '0';
           WHEN B_E1 =>
             IF ( REQ ='1') THEN B_NS <= B_E1;
                            ELSE B_NS <= B_E0;
             END IF;
             DATA_INT <= DATA_IN;
             ACK      <= '1';
         END CASE;
         END IF;
       END PROCESS B_1;

       B_2 : PROCESS( ck )
       BEGIN
           IF ( ck = '1' AND NOT ck'STABLE )
           THEN B_CS <= B_NS;
           END IF;
       END PROCESS B_2;

       END FSM;

SEE ALSO

       vbe(5), syf(1)