UPGRADE YOUR BROWSER

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!

cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Explorer
Explorer
10,515 Views
Registered: ‎11-23-2009

FSM inferred, but not encoded as one_hot

Hi,

 

I have a large FSM, with 113 states. So encoding really does matter, only one_hot gives good timing.

 

After fixing the 'next state signal initialization' issue (see posting) the FSM is inferred, but not re-encoded. I see in the log

INFO: [Synth 8-5534] Detected attribute (* fsm_encoding = "one_hot" *) [...]
INFO: [Synth 8-802] inferred FSM for state register 'R_STATE_reg' in module 'pdp11_sequencer'
.....
---------------------------------------------------------------------------------
Finished RTL Optimization Phase 2 : ...

but no message like

   INFO: [Synth 8-3354] encoded FSM with state register '...' using encoding '...'

 

I've tried with attribute in the code, and with fsm_extract = 'one_hot' synthesis settings.

 

The state register has 7 bits (needed to encode 113 states). The properties of the state flop indicate funny enough

   FSM_ENCODING = 'one_hot'

see attached screen shot.But this is clearly not correct, there are 7 and not 113 state regs. And the logic depth of the next state logic is as deep as the abyss.

 

A screen shot of the message summary and the full synthesis log are also attached.

Side note: this code was happily synthesized by ISE for years resulting in an one_hot encoded FSM.

 

So question:

 

   What can prevent the one_hot encoding of  an inferred FSM ?

 

Any hint/help very welcome,  with best regards,  Walter

 

P.S.: Using Vivado 2016., but 2015.4 shows same behaviour.

snapshot14.png
snapshot15.png
0 Kudos
9 Replies
Visitor wrau0000
Visitor
10,088 Views
Registered: ‎05-04-2016

Re: FSM inferred, but not encoded as one_hot

Check your syntax, I believe the correct syntax is "one-hot" and not "one_hot" as you have entered.

You can set an attribute to almost any value (as your log file noted), but generally only recognized with correct syntax and if invalid there is usually no error message.

Setting to an invalid value results in the default of encoded being used.

0 Kudos
10,076 Views
Registered: ‎07-15-2015

Re: FSM inferred, but not encoded as one_hot

I have definitely seen it work with one_hot (underscore and lowercase); pasting an xdc snippet I just used below in 2015.4:

 

set_property fsm_encoding one_hot [get_cells *curr_st* -filter "is_sequential==TRUE"]

 

"curr_st" is my state register; the *wildcards* are there to match it after synthesis prepends cell names with "FSM_one_hot_" and the is_sequential attribute is there to make sure it only applies to flops in my FSM, not any combo logic that may inherit "curr_st" in part of its name.

 

Not sure what's preventing one_hot encoding of your FSM, unless it's the size, or if the fsm_extraction setting didn't stick.

 

Mine went through fine with 10 states represented by 10 flops. You can see the state remapping in the impl_synth/runme.log file. (Sadly, I haven't found more user-friendly ways to get info like report_fsm.)

 

 

0 Kudos
Xilinx Employee
Xilinx Employee
10,057 Views
Registered: ‎07-21-2014

Re: FSM inferred, but not encoded as one_hot

Hi,

Can you share rtl please.

-Shreyas
----------------------------------------------------------------------------------------------
Try to search answer for your issue in forums or xilinx user guides before you post a new thread.

Kindly note- Please mark the Answer as "Accept as solution" if information provided solves your query.
Give Kudos (star provided in right) to a post which you think is helpful and reply oriented.
----------------------------------------------------------------------------------------------
0 Kudos
10,026 Views
Registered: ‎07-15-2015

Re: FSM inferred, but not encoded as one_hot

My initial reply was a bit hasty; upon closer reading, it looks like you did everything right.

 

FWIW, it was easy to extend my trivial 10-state FSM to 113 states, encoded as one_hot, and confirm that the synthesized result contained 113 state registers.

 

On caveat though, is that the FSM extraction/optimization takes place during synthesis, meaning that if you look at the RTL schematic and netlist pane viewer after elaboration, you will only see 7 flip-flops for the state register. After synthesis, I see the change from 7 to 113 in mine.

 

However, I also observed something odd in the final result: My curr_st reg declaration used an enumerated type with 113 states defined externally in a package. That way, I could output a copy of the state register values to a top-level port, and leave the entity declaration of that port generic enough allow adjustment of bit width based on the chosen encoding:

 

 

package types is
  type t_state is (s0, s1, s2, s3, s4, s5, s6, s7, s8, s9,
    s10, s11, s12, s13, s14, s15, s16, s17, s18, s19,
    s20, s21, s22, s23, s24, s25, s26, s27, s28, s29,
    s30, s31, s32, s33, s34, s35, s36, s37, s38, s39,
    s40, s41, s42, s43, s44, s45, s46, s47, s48, s49,
    s50, s51, s52, s53, s54, s55, s56, s57, s58, s59,
    s60, s61, s62, s63, s64, s65, s66, s67, s68, s69,
    s70, s71, s72, s73, s74, s75, s76, s77, s78, s79,
    s80, s81, s82, s83, s84, s85, s86, s87, s88, s89,
    s90, s91, s92, s93, s94, s95, s96, s97, s98, s99,
    s100, s101, s102, s103, s104, s105, s106, s107, s108, s109,
    s110, s111, s112);
end package types;


library ieee;
use ieee.std_logic_1164.all;

 

library work;
use work.types.all;

 

entity state_mach is port (
  rst : in std_logic;
  clk : in std_logic;
  run : in std_logic;
  odd : in std_logic;
  err : out std_logic;
  smon : out t_state);  -- intended as arbitrary, generically adjustable width, for state register monitor
end entity state_mach;

 

The end result though, is that despite having 113 state registers for the 1-hot FSM, Vivado generates logic to re-encode those 113 bits into a 7-bit vector, and generates a 7-bit output port for smon.

 

It's sort of a chicken/egg problem about picking port widths in the entity first, or recognizing the FSM and choosing an encoding first to drive the port width. I'm not sure if VHDL has a rule for that, or if the result is tool-dependent, but I found it to be an interesting choice (generating all that logic to re-encode outputs as 7-bit).

 

Sorry to wander a little bit off topic, but I thought this might be of interest to Xilinx. :)

 

 

0 Kudos
Explorer
Explorer
9,447 Views
Registered: ‎11-23-2009

Re: FSM inferred, but not encoded as one_hot

Hi @wrau0000,

 

it's definitly 'one_hot' in vivado. For differences to ISE and log file confusion in vivado see this post on "one_hot and one-hot".

 

Regards Walter

0 Kudos
Explorer
Explorer
9,443 Views
Registered: ‎11-23-2009

Re: FSM inferred, but not encoded as one_hot

Hi @aher,

 

was traveling, so sorry for the delay in answering your request.

 

The source is attached as ready to use vivado 2016.1 project in example_project.tar.

Just untar and

     vivado -mode gui project_mflow/project_mflow.xpr

Use -fsm-extraction one_hot. The FSM is recognized, but not re-encoded.

The synthesis log from vivado is attached too as vivado_syn.txt.

The same source synthesizes well under ISE since many revisions and gives a one_hot encodes FSM. The xst log for SIE 14.7 is attached as ise_xst.txt.

 

And two notes:

  • initially I thought that the procedures using 'nstate' as inout argument where the culprit. I setup some test cases with similar structured state machines, but they all resukted in one_hot encodes FSMs. So there must be other factors.
  • this FSM is indeed a monster. The the central part of a historical CISC processor. The whole project is open source and on opencores as project 'w11'.
0 Kudos
Explorer
Explorer
9,279 Views
Registered: ‎11-23-2009

Re: FSM inferred, but not encoded as one_hot

Hi @aher,

 

after some more systematic testing I localized the culprit !

 

At the very end of the admittedly very large and complex state machine is a 'state number generator' which generates a state number based on the current state. It is implmented in a very straight forward way in proc_snum like

 

  proc_snum : process (R_STATE)
    variable isnum : slv8 := (others=>'0');
  begin
    isnum := (others=>'0');
    case R_STATE is
      when s_idle           => isnum := x"00";
      when s_cp_regread     => isnum := x"01";
      when s_cp_rps         => isnum := x"02";
      .....
      when others           => isnum := x"ff";
    end case;
    DM_STAT_SE.snum   <= isnum;
  end process proc_snum;

 

This construct prevents that the FSM is re-encoded as 'one_hot'.

 

I have added 3 ready to use vivado 2016.1 projects

  • example_orig.tar: it contains the design with the original 'proc_snum'. You'll get a
       INFO: [Synth 8-802] inferred FSM for state register 'R_STATE_reg' in module 'pdp11_sequencer'
    but R_STATE is encoded in some binary form.
  • example_nosnum.tar: it contains the design with 'proc_snum' simply deleted. Now one gets also a
      INFO: [Synth 8-3354] encoded FSM with state register 'R_STATE_reg' using encoding 'one-hot' in ...
    and the FSM is indeed re-encoded as one_hot.
  • example_part.tar: it contains 'proc_snum', but only the first few states are mapped, the rest is defaulted. In this (not practical useful) case one also gets a 'INFO: [Synth 8-3354]', the FSM is indeed re-encoded as one_hot. That shows the the basic case-when contruction is not the cause.

Bottom line is that even though that one_hot encoding was explicitely requested via

     attribute fsm_encoding : string;
     attribute fsm_encoding of R_STATE : signal is "one_hot";

the synthesis under some circumstances decides to go for some form of binary encoding.

 

  • This is bad in itself.
  • That there is no 'INFO: [Synth 8-3354]' stating which encoding was used makes it worse.
  • That there is no message indicating why things like this happen makes it very intransparent.

With best regards,  Walter

0 Kudos
Explorer
Explorer
9,168 Views
Registered: ‎11-23-2009

Re: FSM inferred, but not encoded as one_hot

Hi @aher,

 

I've tried to create a reproducer for this problem, but that failed, in an interesting way.

I've created a FSM with 120 states and enough transitions that they all are reached.

And I've added the 'state number generator' logic, which caused the problems, as

 

  proc_snum : process (R_STATE)
    variable isnum : slv7 := (others=>'0');
  begin
    isnum := (others=>'0');
    case R_STATE is
      when s_000            => isnum := slv(to_unsigned(  0,7));
      when s_001            => isnum := slv(to_unsigned(  1,7));
      ... snip
      when s_118            => isnum := slv(to_unsigned(118,7));
      when s_119            => isnum := slv(to_unsigned(119,7));
      when others           => isnum := "1111111";
    end case;
    SNUM  <= isnum;
  end process proc_snum;

A ready to use vivado 2016.1 project with the sources is attached as example_reproducer.tar.

 

The surprise is that this code happily synthesizes and gives a one_hot encoded FSM, the log file has

 

   INFO: [Synth 8-802] inferred FSM for state register 'R_STATE_reg' in module ...

   INFO: [Synth 8-3354] encoded FSM with state register 'R_STATE_reg'

        using encoding 'one-hot' in ...

 

So the construct used in proc_snum, which decodes all states and generates the binary number, is not the only reason why the code send with example_orig.tar doesn't  produce a properly encode FSM. There must be another factor involved.

 

Any help or hint to resolve this is highly welcome.

 

With best regards,  Walter

 

 

0 Kudos
Explorer
Explorer
9,128 Views
Registered: ‎11-23-2009

Re: FSM inferred, but not encoded as one_hot

john.johnson2@rockwellcollins.com, (cc: @aher)

 

you wrote

  "Sorry to wander a little bit off topic, but I thought this might be of interest to Xilinx. :)"

 

Turned out that exactly such a 'state number generator' is causing the observed problem. See here and here in this thread.  The issue raised in this thread is that vivado recognizes a FSM, and than refuses to re-encode it, even though one_hot is requested via fsm_extraction and as signal attribute. This without any INFO or WARNING. That should definitely not happen and imho should be corrected in vivado.

 

So I started to look for other ways to express it an tried

    to_unsigned(state_type'pos(R_STATE),7)

I posted the surprising outcome is a separate thread.

 

 

 

0 Kudos