XST fails to recognize FSM with registered outputs

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From English to

Threaded View
Hi everybody,
while I was trying to create a statemachine with registered outputs
which shouldn't be delayed by one clock cycle (as usual when just
putting a register behind the outputs of the FSM) I modified some
sourcecode from the XILINX ISE Language Templates for sythesis. As an
example I tried to recreate the stopwatch statemachine from the ISE 5
In depth tutorial.

Everything works fine insofar that the function is correct and
itentical to the original design and it also synthesizes fine with one
little exeption:

The XST-Synthesis Tool does not recognize my coding style as a FSM,
therefore it wont do the neccessary optimizations. For comparision
purposes I have added some XST-synthesis report snippets to outline
the differences:

While my coding style produces a register and some feedback logic
around it, for the original code (Produced by StateCAD) XST inferes a
FSM and applies all optimizations on it.

(When I comment out the enum_encoding attributes in my code then
register CS will become One-State-Hot encoded, but no OSH-FSM will be
created. Instead some clumsy binary FSM with an unreal OSH encoding
(all statebits zero!!! - not allowed for OSH encoding!!!) will be
generated.

So, what trick makes the XST-Synthesis tool recognize my coding style
to be a FSM working in the way I want (that is with registered outputs
but no delay by one clock cycle)?


All help is appreciated.

Thanks

 Eilert



=========================================================================
*                           HDL Synthesis                            
 *
=========================================================================

Synthesizing Unit <elis_statemachine>.
    Related source file is
S:/ssy_laboratory_test/ssy_stopwatch/ELIS_Statemachine.vhd.
    Found 1-bit register for signal <clockenableout>.
    Found 1-bit register for signal <resetout>.
    Found 3-bit register for signal <cs>.
    Summary:
    inferred   5 D-type flip-flop(s).
Unit <elis_statemachine> synthesized.


=========================================================================
HDL Synthesis Report

Macro Statistics
# Registers                        : 3
  3-bit register                   : 1
  1-bit register                   : 2

=========================================================================



=========================================================================
*                           HDL Synthesis                            
 *
=========================================================================

Synthesizing Unit <stmach>.
    Related source file is
S:/ssy_laboratory_test/ssy_stopwatch/STMACH.vhd.
    Found finite state machine <FSM_0> for signal <sreg>.
    -----------------------------------------------------------------------
    | States             | 6                                          
   |
    | Transitions        | 11                                        
   |
    | Inputs             | 1                                          
   |
    | Outputs            | 2                                          
   |
    | Reset type         | asynchronous                              
   |
    | Encoding           | automatic                                  
   |
    | State register     | d  flip-flops                              
   |
    -----------------------------------------------------------------------
    Summary:
    inferred   1 Finite State Machine(s).
Unit <stmach> synthesized.


=========================================================================
HDL Synthesis Report

Macro Statistics
# FSMs                             : 1

=========================================================================

Optimizing FSM <FSM_0> with One-Hot encoding and d flip-flops.



Sourcecode of elis_statemachine.vhd:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity ELIS_Statemachine is
    Port ( Clock : in std_logic;
           Reset : in std_logic;
           StartStop : in std_logic;
           ClockEnableOut : out std_logic;
           ResetOut : out std_logic);
end ELIS_Statemachine;

architecture Behavioral of ELIS_Statemachine is
  type STATE_TYPE is (Clear,Zero,Start,Counting,Stop,Stopped);    
  attribute ENUM_ENCODING: STRING;
  attribute ENUM_ENCODING of STATE_TYPE: type is "000 101 010 001 011
100";
  signal CS    : STATE_TYPE;
  signal NS : STATE_TYPE;

begin
      
    SYNC_PROC: process (CLOCK, RESET)
    begin
       if (RESET='1') then
              CS <= Clear;
       elsif (CLOCK'event and CLOCK = '1') then
            CS <= NS;
       end if;
    end process;
 
    COMB_PROC: process (CS, StartStop)
    begin
       case CS is
          when clear => NS <= Zero;
        when Zero  => If StartStop = '1' then
                        NS <= Start;
                  else
                    NS <= Zero;
                  end if;
        when Start  => If StartStop = '0' then
                        NS <= Counting;
                  else
                    NS <= Start;
                  end if;
        when Counting  => If StartStop = '1' then
                              NS <= Stop;
                      else
                      NS <= Counting;
                          end if;
        when Stop  => If StartStop = '0' then
                        NS <= Stopped;
                  else
                    NS <= Stop;
                      end if;
        when Stopped  => If StartStop = '1' then
                           NS <= Zero;
                     else
                       NS <= Stopped;
                         end if;
            when others =>    NS <= Clear;
       end case;
    end process;
 
    Sync_Output : process (Reset, Clock)
    begin
       if (RESET='1') then
        ClockEnableOut <= '0';
          ResetOut <= '1';
      elsif (CLOCK'event and CLOCK = '1') then
        case NS is
            when clear =>     ClockEnableOut <= '0';
                         ResetOut <= '1';
         when Zero  =>     ClockEnableOut <= '0';
                         ResetOut <= '0';
          when Start  =>    ClockEnableOut <= '1';
                         ResetOut <= '0';
         when Counting  => ClockEnableOut <= '1';
                         ResetOut <= '0';
         when Stop  =>     ClockEnableOut <= '0';
                         ResetOut <= '0';
         when Stopped  =>  ClockEnableOut <= '0';
                         ResetOut <= '0';
           when others =>    ClockEnableOut <= '0';
                         ResetOut <= '1';
       end case;
      end if;
    end process;

end Behavioral;



Sourcecode of stmach.vhd :

LIBRARY ieee;
USE ieee.std_logic_1164.all;

ENTITY STMACH IS
    PORT (CLK,RESET,strtstop: IN std_logic;
        clkout,rst : OUT std_logic);
END;

ARCHITECTURE BEHAVIOR OF STMACH IS
    SIGNAL sreg : std_logic_vector (2 DOWNTO 0);
    SIGNAL next_sreg : std_logic_vector (2 DOWNTO 0);
    CONSTANT clear : std_logic_vector (2 DOWNTO 0) :="000";
    CONSTANT counting : std_logic_vector (2 DOWNTO 0) :="001";
    CONSTANT start : std_logic_vector (2 DOWNTO 0) :="010";
    CONSTANT stop : std_logic_vector (2 DOWNTO 0) :="011";
    CONSTANT stopped : std_logic_vector (2 DOWNTO 0) :="100";
    CONSTANT zero : std_logic_vector (2 DOWNTO 0) :="101";

BEGIN
    PROCESS (CLK, RESET, next_sreg)
    BEGIN
        IF ( RESET='1' ) THEN
            sreg <= clear;
        ELSIF CLK='1' AND CLK'event THEN
            sreg <= next_sreg;
        END IF;
    END PROCESS;

    PROCESS (sreg,strtstop)
    BEGIN
        clkout <= '0'; rst <= '0';

        next_sreg<=clear;

        CASE sreg IS
            WHEN clear =>
                clkout<='0';
                rst<='1';
                IF  TRUE THEN
                    next_sreg<=zero;
                 ELSE
                    next_sreg<=clear;
                END IF;
            WHEN counting =>
                clkout<='1';
                rst<='0';
                IF  NOT ( (( strtstop='0' ) ) OR  (( strtstop='1' ) ) ) THEN
                    next_sreg<=counting;
                END IF;
                IF ( strtstop='0' ) THEN
                    next_sreg<=counting;
                END IF;
                IF ( strtstop='1' ) THEN
                    next_sreg<=stop;
                END IF;
            WHEN start =>
                clkout<='1';
                rst<='0';
                IF  NOT ( (( strtstop='1' ) ) OR  (( strtstop='0' ) ) ) THEN
                    next_sreg<=start;
                END IF;
                IF ( strtstop='1' ) THEN
                    next_sreg<=start;
                END IF;
                IF ( strtstop='0' ) THEN
                    next_sreg<=counting;
                END IF;
            WHEN stop =>
                clkout<='0';
                rst<='0';
                IF  NOT ( (( strtstop='1' ) ) OR  (( strtstop='0' ) ) ) THEN
                    next_sreg<=stop;
                END IF;
                IF ( strtstop='1' ) THEN
                    next_sreg<=stop;
                END IF;
                IF ( strtstop='0' ) THEN
                    next_sreg<=stopped;
                END IF;
            WHEN stopped =>
                clkout<='0';
                rst<='0';
                IF  NOT ( (( strtstop='0' ) ) OR  (( strtstop='1' ) ) ) THEN
                    next_sreg<=stopped;
                END IF;
                IF ( strtstop='0' ) THEN
                    next_sreg<=stopped;
                END IF;
                IF ( strtstop='1' ) THEN
                    next_sreg<=start;
                END IF;
            WHEN zero =>
                clkout<='0';
                rst<='0';
                IF  NOT ( (( strtstop='0' ) ) OR  (( strtstop='1' ) ) ) THEN
                    next_sreg<=zero;
                END IF;
                IF ( strtstop='0' ) THEN
                    next_sreg<=zero;
                END IF;
                IF ( strtstop='1' ) THEN
                    next_sreg<=start;
                END IF;
            WHEN OTHERS =>
        END CASE;
    END PROCESS;
END BEHAVIOR;

Re: XST fails to recognize FSM with registered outputs
Dear Eilert,

The description style you used in ELIS_Statemachine example will be
supported in the next release of ISE.

In the case you replace
         case NS is
by
         case CS is

in the process

    Sync_Output : process (Reset, Clock)

then XST will be able to recognize FSM (but of course in this case it is
not the same behavior).

Thank you,
Sergei.

E. Backhus wrote:
Quoted text here. Click to load it


Re: XST fails to recognize FSM with registered outputs
Hi,

I've already arise this question few month ago : Does XST will be able
soon to code FSM in a safe way : ie be able to create a one-hot
encoding and recognize the 'when others" clause.
Ex :
 ...
 when Sate_one =>          
   ...
 when others => My_State <= INIT;

Is very important in case where clock can disappear or other strange
things happen (this case arise in telecom application when user
disconnect or connect fiber or when DCM start...). With 'safe'
encoding we are sure to be in a know state.

For me is a very important feature and a basic feature for a
synthesizer (FpgaExpress had it for many years, the same for Simplify
and others) : that's why synthesizer was created at the beginning:
recognize counter, adder and FSM correctly. Others features came
later.
It's the main reason why I can use XST.

Note : binary coding or a kind of global reset is not a solution for
me and would be a backward step : I don't want to change all my
'correct vhdl' to use xst.

Quoted text here. Click to load it

Site Timeline