Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support setting FSM encoding attribute #135

Closed
mithro opened this issue Jul 7, 2019 · 3 comments
Closed

Support setting FSM encoding attribute #135

mithro opened this issue Jul 7, 2019 · 3 comments
Labels

Comments

@mithro
Copy link

mithro commented Jul 7, 2019

To get make sure your FSM state variable stays as a specific encoding, most synthesis tools support setting an encoding attribute on the state register. This appears to be something that Synopsys Synplify added and then everyone else copied for compatibility (Quartus II + Libero + Diamond).

reg [7:0] current_state /* synthesis syn_encoding="safe,gray" */;
(* syn_encoding = "safe" *) reg [2:0] my_fsm;

A list of the valid encoding schemes seems to be;

  • binary,
  • onehot,
  • twohot,
  • sequential,
  • gray,
  • random,
  • original,

There also seems to be an extra safe value which can be added;

The Safe State Machine option and corresponding syn_encoding
attribute value safe specify that the software should insert extra logic to
detect an illegal state and force the state machine’s transition to the reset
state.

It would be good to be able to do this with nMigen.

@whitequark
Copy link
Contributor

whitequark commented Jul 7, 2019

I'm not yet convinced nMigen needs to provide an abstraction for this. In particular, what if you request e.g. a twohot encoding but the selected backend e.g. Yosys cannot do it?

Also, it seems to be a niche feature with more potential for misuse than use, like full_case. I've played with Yosys' FSM passes and each time I got them to work on my code, the FSM became bigger and slower...

If you're fine adding platform-specific attributes, you can already do this with:

with m.FSM() as fsm:
    fsm.state.attrs["syn_encoding"] = "onehot"

@mithro
Copy link
Author

mithro commented Jul 7, 2019

FYI - Here is what Vivado says about FSM state encoding;

Vivado synthesis attempts to select the best-suited encoding method for a given FSM.

One-Hot State Encoding

One-Hot State encoding has the following attributes:
• Is the default encoding scheme for state machine up to 32 states.
• Is usually a good choice for optimizing speed or reducing power dissipation.
• Assigns a distinct bit of code to each FSM state.
• Implements the State Register with one flip-flop for each state.
• In a given clock cycle during operation, only one bit of the State Register is asserted.
• Only two bits toggle during a transition between two states.

Gray State Encoding

Gray State encoding has the following attributes:
• Guarantees that only one bit switches between two consecutive states.
• Is appropriate for controllers exhibiting long paths without branching.
• Minimizes hazards and glitches.
• Can be used to minimize power dissipation.

Johnson State Encoding

Johnson State encoding is beneficial when using state machines containing long paths with
no branching (as in Gray State Encoding).

Sequential State Encoding

Sequential State encoding has the following attributes:
• Identifies long paths
• Applies successive radix two codes to the states on these paths.
• Minimizes next state equations.

It may be that it is impossible to know the best FSM state encoding until you have timing information?

Sorry, something went wrong.

@whitequark
Copy link
Contributor

I think for now, the above fsm.state.attrs["encoding"] = "..." solution is sufficient since the attribute and its effects are very toolchain specific; and moreover, the toolchain defaults seem to be quite reasonable. If there is good motivation, we can always add an abstraction for this later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants