We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

Showing results for 
Search instead for 
Did you mean: 
Registered: ‎11-23-2009

Vivado FSM inference create spurious state named 'iSTATE'



The brief summary:


The vivado FSM inference does not recognize under some circumstances a common coding pattern of two process FSMs and generates a spurious state


and faulty transitions into this state. The generated FSM is broken.


The short story:


The following coding pattern of a two process FSM


  signal R_STATE : state_type := s_idle;
  signal N_STATE : state_type;

  proc_regs: process (CLK)
    if rising_edge(CLK) then
      R_STATE <= N_STATE;
    end if;
  end process proc_regs;

  proc_next: process (R_STATE, ... other inputs...)

    case R_STATE is
      when s_xxxx =>
        if .. some condition.. then
          N_STATE <= s_yyyy;
          .. some code, no assignment to N_STATE !!
        end if;
    end case;

  end process proc_next;



   if condition fulfilled transition to s_yyyy, otherwise stay in current state

The line

should setup the current state as next state unless N_STATE is explicitly set otherwise. Quite common coding pattern.


Vivado misses it sometimes and creates instead a transition to an additional state iSTATE.


The long story:


when porting a design from ISE to Vivado I saw that in two modules the FSM inference created much to my surprise an additional state named iSTATE. The synthesis log looks like


       State |        New  |      Prev  
      s_idle |        0001 |        00
    s_cpwait |        0010 |        01
    s_cpstep |        0100 |        10
      iSTATE |        1000 |        11


In one case I could prune the code down to a small reproducer, sources and synthesis logs are attached. I see this 'iSTATE' creation for vivado 2016.1, 2015.4 and 2015.1.

Inspecting the post-synthesis schematics reveals that the state flop associated with the iSTATE (named FSM_onehot_R_STATE_reg[3]) connects to nothing, see attached screen shot. Looking into the logic shows that this state is reached when


  FSM_onehot_R_STATE_reg[1]/Q   is 0
  FSM_onehot_R_STATE_reg[0]/Q   is 0
  STAT_STEP_IBUF_inst/O         is 1
  MREQ_ENA_IBUF_inst/O          is 1


Assuming proper functioning of a one_hot encoded fsm this is equivalent to


  FSM_onehot_R_STATE_reg[2]/Q = '1'  and 
  STAT_STEP_IBUF_inst/O       = '1'  and
  MREQ_ENA_IBUF_inst/O        = '1'

which corresponds in the sources to

      when s_cpstep =>
        if MREQ_ENA='0' then
          nstate := s_idle;
          if STAT_STEP = '0' then
            nstate := s_idle;
            irb_busy := '1';           -- <==  THIS CASE
          end if;
        end if;


Apparently the synthesizer does not recognize that nstate has been defined before the case statement with

    nstate := R_STATE;

Creation of an iSTATE stops when the next state is defined in the 'when' clause in one of the two places indicated in the code below

      when s_cpstep =>                  -- s_cpstep: wait for cpustep done ---
--      nstate := s_cpstep;             -- <==== iSTATE FIX 1
        if MREQ_ENA='0' then                -- rbus cycle abort
        nstate := s_idle;                 -- quit
          if STAT_STEP = '0' then      -- cpustep done
            nstate := s_idle;
--          nstate := s_cpstep;        -- <==== iSTATE FIX 2
            irb_busy := '1';
          end if;
        end if;


The attached tar ball contains
      rep_istate.vhd            <-- example using variable for nstate
   rep_istate1.vhd           <-- same, no using a variable for nstate
   rep_istate_syn_iSTATE.log <-- synthesis log, both 'iSTATE FIX' commented
   rep_istate_syn_FIX1.log   <-- synthesis log with 'iSTATE FIX 1'
   rep_istate_syn_FIX2.log   <-- synthesis log with 'iSTATE FIX 2'


Final notes:

  • the original code happily runs with ISE since many years
  • the original code works with Vivado as long as no fsm is inferred ! The 'next_state signal initialization issue' so far prevented fsm inference and saved the design !
  • the issue has nothing to do with the intermediate variable used in the example. rep_istate1.vhd is a version with direct assignment of N_STATE and shows the same problem.
0 Kudos
3 Replies
Registered: ‎11-23-2009

Re: Vivado FSM inference create spurious state named 'iSTATE'



I've further pruned down the iSTATE reproducer, and also written a small test bench. See attached tar ball.


The synthesis still produces the state 'iSTATE'. The schematic looks still strange, there is an additional state flop named FSM_onehot_R_STATE_reg[3] which is associated with the 'iSTATE'.


BUT: the test bench runs fine for both behavioural simulation as well as post-synthesis functional simulation !


Reason is: The D pin and the CE pin of FSM_onehot_R_STATE_reg[3] are never '1' simultaneously !

See attached ScreenShot,  FSM_onehot_R_STATE[3]_i_2_n_0 goes to D and FSM_onehot_R_STATE[3]_i_1_n_0 to CE. In cycle 10 D is '1', but since the FSM should stay in this state, CE is '0'. So there is an additional state flop, but there seems never to be a transition to it.


So bottom line of this story is:

  • A spurious state name 'iSTATE' is created
  • superfluous logic is created (state flop and associated combinatorial logic)
  • but the FSM works as expected, and is not broken as initially assumed

Nevertheless this is a very strange behaviour of the FSM inference, and imho should be corrected.


When I see a synthesis report where additional states are added I get nervous, and rightfully so.


0 Kudos
Registered: ‎11-23-2009

Re: Vivado FSM inference create spurious state named 'iSTATE'

Hi *,


I had several FSMs which had the iSTATE plague (and I know of designs done by others also afflicted by this disease). When I went through systematically I saw that the iSTATE is inserted in the re-conding listing always right after the state which triggers the iSTATE generation. E.g. in


              State |       New Encoding |   Old Encoding
             s_idle |     00000000000001 |    0000
             s_mcmd |     00000000000010 |    0001
        s_mcmd_read |     00000000000100 |    0010
           s_sstart |     00000000001000 |    1001
            s_sload |     00000000010000 |    1010
             s_srun |     00000000100000 |    1011
            s_sloop |     00000001000000 |    1100
         s_mblk_wr1 |     00000010000000 |    0011
         s_mblk_wr2 |     00000100000000 |    0100   <-- state to be fixed !!!
             iSTATE |     00001000000000 |    1111
         s_mblk_rd1 |     00010000000000 |    0101
         s_mblk_rd2 |     00100000000000 |    0110
             s_sblk |     01000000000000 |    1000
          s_sblk_rd |     10000000000000 |    0111


the state s_mblk_wr2 is the trigger. I always add something like

when s_cpstep => -- s_cpstep: ---
N_STATE <= s_cpstep;

To be crystal clear: the vhdl is clean, no latches ect, the additional statement is absolutely superfluous, except to calm down vivado. I have very many states where the next state is not defined under all if/case conditions in a given when and where the logic relies on the "N_STATE <= R_STATE" before the 'case. Only in a few vivado fails and creates an iSTATE. So far I didn't see a pattern.

0 Kudos
Registered: ‎11-23-2009

Re: Vivado FSM inference create spurious state named 'iSTATE'

Just tried the reproducer with vivado 2016.2.

Still same behavior, a spurious state 'iSTATE' is generated.


Again, I consider this a bug at several levels

  • apparently the source isn't analyzed correctly, which triggers creation of an additional state
  • even if there were good reasons to create a new state, is should be indicated with a message
  • logic is created which is apparently (and hopefully) never used

The iSTATE cases I have seen (also in sources from other developers) seem not to cause functional problems, the state is created but the transition to this state is never taken. But who knows whether that's always the case.


Tags (1)
0 Kudos