Finite State Machine (FSM) optimization is part of synthesis. You can write an FSM in either VHDL or Verilog, and your synthesis tool can re-code the states according to your specification. However sometimes your synthesis tool may appear to ignore your commands - this section looks at some reasons why this might happen.
The examples in this section use VHDL attributes to define the required coding - the same ideas can be used in Verilog, but using meta-comments (special comments that are interpreted by the synthesis tool).
Using Synopsys Synplify Pro® with FSMs
The default behaviour of Synplify is to "do its best" - finite state machine optimization if fully automatic.
According to the Synplify documentation, you can control state machine optimization in two ways, firstly be specifying the codes you want:
type StateType is (Idle, Start, Stop, Clear); attribute syn_enum_encoding: string; attribute syn_enum_encoding of StateType: type is "001 010 100 111";
and secondly by specifying the kind of coding:
attribute syn_encoding: string; attribute syn_encoding of State: signal is "sequential,safe";
However for either of these to work, you must turn off FSM Compiler i.e. make sure the option FSM Compiler is not checked.
In a Tcl script, use the command:
set_options -symbolic_fsm_compiler 0 # or set_options -autosm 0
Using Xilinx XST with FSMs
XST allows control of finite state machines using attributes or from the GUI. However XST will ignore attributes (or meta-comments in Verilog) unless you set the FSM mode to "user". Here is an example of synthesis of a simple enumerated type and the results:
type StateType is (Zero, Start, Running, Stop, Stopped, Reset); attribute enum_encoding : string; attribute enum_encoding of statetype : type is "001 010 100 110 111 101";
and here is the resulting encoding after synthesis with XST:
Analyzing FSM <FSM_0> for best encoding. Optimizing FSM <State/FSM> on signal <State[1:3]> with sequential encoding. --------------------- State | Encoding --------------------- zero | 000 start | 001 running | 010 stop | 101 stopped | 011 reset | 100 ---------------------
Hmmm... that doesn't look right. To get our attribute to have an effect, we need to set the encoding algorithm to User. To do this from the GUI:
- Right clock on the XST-Synthesize process
- Select Properties...
- Highlight HDL Options
- Set FSM Encoding Algorithm to User
To do the same using an attribute, use the code:
signal State, NextState: StateType; attribute fsm_encoding: string; attribute fsm_encoding of State : signal is "User";
Now after synthesis, the encoding is:
--------------------- State | Encoding --------------------- zero | 001 start | 010 running | 100 stop | 110 stopped | 111 reset | 101 ---------------------
as we intended.