State Machine Guidelines
Using FSMs for future designs can be a great help, in terms of visualizing
the design as well as simplifying debugging. We must warn you though, that
many of the students who had the most difficulty in previous semesters used
state machines -- probably because they violated one of the rules below.
FSMs hide much of the complexity going on in the underlying VHDL, but you must
use good design practices to allow HdlDesigner to generate a reliable FSM. The
following is a listing of tips that will help you to create a reliable state
machine that can be reused in a variety of designs.
- Drive all FSMs with the same clock
– Many students find it convenient
to clock a PS/2 FSM with PS2_DATA_H or a sound codec FSM with SCLK. This is
fine for one design, but later on when you want to combine FSMs into a single
design, you run into problems. In general, you should clock all FSMs with the
fastest clock available, which is the board clock. Clock signals in your
design are treated special on the Virtex chip, as they are assigned a global
clock buffer which provides a low skew signal to the whole chip. Using
multiple clocks runs the risk of one clock not being assigned a GCLKBUF,
resulting in timing problems.
- Use Default Values
– Every FSM output is assigned a "default value" in
state machine properties. This can be a help, as one only has to assign a
value when it is not the default. Understand, though, that this behavior is
counter to what you would expect when writing custom VHDL. In VHDL, you expect
your signal assignment to stay the same until you explicitly change it. With
FSMs, the lack of a signal assignment in a state assumes the default value.
- Understand Combinatorial Outputs
– By default, all outputs are
combinatorial, as selected in the "signal status" tab of state machine
properties. Combinatorial outputs are fine, given that one understands the
limitations. First, one must always assign a default value to a combinatorial
output. Not doing so can create latches during synthesis. Second, know that a
combinatorial output is assigned at the current state – behaving like a "Moore
machine." Third, combinatorial outputs will glitch as the corresponding inputs
change – it is only guaranteed to be stable by the next clock edge. The last
point is generally not a concern.
- Understand Registered Outputs
– For reasons discussed in 3, a
combinatorial output may not be suitable for your design. Instead, you may use
a registered output. Registered outputs do not glitch, nor do they require a
default value (although it is good to have one). The drawback is that your FSM
now behaves as a "Mealy machine." Registered outputs change on the clock edge
of your FSM, meaning that all changes to outputs occur on the state
transitions rather than in the current state. This fundamental difference
often results in different behavior of outputs when changing from
combinatorial to registered signals.
- Use a Recovery State
– In state machine properties, you may define a
recovery state which the machine will enter if the next state variable is
invalid. Have this state output some recognizable error signal to the board.
By default, the recovery state is the default state, so if your FSM encounters
an invalid state, it will automatically enter what most people define as their
reset state. If your FSM ever enters the recovery state, you have likely
violated one of the other rules in this list.