Designing Reliable VHDL Finite State Machines.

Written by Tom on Friday 25/05/07

In this article we discuss how to design a reliable Finite State Machine by following the below VHDL design rules.

1. Use a two process Entity structure.

2. Selection of encoding style.

3. Ensure all signals used in the Process appear in the process list.

4. Ensure all combinations of input/output signals are included in the code.

5. Ensure all outputs of the FSM are registered.

6. Ensure all input are synchronous.

two process entity

Use a two process Entity structure.

The above diagram shows the interaction between the two processes.

By using two processes for each entity we gain the following advantages.

• Provide uniform algorithm encoding

• Increase abstraction level

• Improve readability

• Clearly identify sequential logic

• Simplify debugging

• Improve simulation speed

• Provide one model for both synthesis and simulation

Lower process. Sequential logic.

Contains the asynchronous reset which determines the initial state of the system, followed by the synchronous storage of nx_state (next state) which will produce pr_state (previous state) at the lower sections output and the storage for any outputs.

An advantage is that number of flips-flops inferred from the code is only storage for outputs and the bits needed to encode all states of the FSM.

Code example:

sequential : process(clk, reset)


if(reset = '1') then

pr_state <= stateA;

elsif (clk'event and clk = '1') then

x <= temp; -- this is where the output is registered

pr_state <= nx_state;

end if;

end process;

Upper process. Combinational logic.

Can be fully combinational (no storage), but for a FSM sequential (CASE statement) coding is used.

Code example:

combinational : process(a, b, d, pr_state)


case pr_state is

when stateA =>

temp <= a;

if (d = '1') then

nx_state <= stateB;


nx_state <= stateA;

end if;

when stateB =>

temp <= b;

if (d = '1') then

nx_state <= stateA;


nx_state <= stateB;

end if;

when others =>

nx_state <= stateA;

end case;

end process;

All state machines outputs shall always be registered.

As shown in above sequential code snippet x <= temp will infer a register therefore storage.

Selection of encoding style.

One hot uses one flip-flop per state.

Pros: Requires least amount of logic and is fastest.

Cons: Uses the largest num of flip-flops 7 states requires 7 flip-flops.

Two hot uses two active bits per active state.

Pros: More efficient than One hot, n bits, n(n-1)/2 states.

Binary (default).

Pros: Uses least number of flip-flops, 2**n states, where n is bits.

Cons: Requires more logic and slower.

State Binary Twoshot Oneshot

State0 000 0011 00000001

State1 001 0101 00000010


Ensure all signals used in the Process appear in the process list.

All signals that are used in the process must be in the process sensitivity list. Although leaving out a signal from the sensitivity list will probably not cause the code to fail synthesis it will throw up some warning. It is good coding practice and adds to code completeness.

Ensure all combinations of input/output signals are included in the code.

Failure to ensure that the input/output truth table is complete can cause latches to be inferred in order to hold their previous values.

if (a =
‘1’) then

b := ‘0’;

end if;

The above is incomplete what is b when a /= ‘1’? A latch may be inferred in this instance. Better code is;

if (a = ‘1’) then

b := ‘0’;


b := ‘1’;

end if;

Use others statement.

The When Others => statement is suppose to ensure that any unused state will be trapped and therefore not put the FSM into an unknown state, but this comes down to the synthesizer, if the error protection is too complicated or not intuitive to the synthesizer it may be synthesized away.

You can add synthesis attributes to ensure that the error protection is not synthesized away (Your synthesizer must support 1076.6-2004 (VHDL RTL synthesis standard)).

type StateType is (S0, S1, S2, S3, S4);

signal state, next: StateType;

attribute FSM_STATE of state : signal is

"0000 0011 0110 1100 1001" ;

attribute FSM_COMPLETE of state : signal is TRUE;

In the example above, the VHDL specification contains five

state values: S0, S1, S2, S3, and S4.

FSM_STATE specifies the encoding to be a four bit array

with S0 = 0000, S1 = 0011, S2 = 0110, S3 = 1100, and S4 = 1001.

The implementation contains 2**4 states = 16.

There are eleven states in the implementation that are not part of
the VHDL specification.
Since FSM_COMPLETE is true, the transition for the eleven unused
states is the the state specified in the others clause.

Ensure all outputs of the FSM are registered.

Registered outputs give the following advantages.

•Outputs (control signals for datapath) change faster (after register
delay only). FSM output logic delay is removed from the critical path.

•Additionally, glitches from the outputs are removed. But still, in a
synchronous design, the outputs should be used to enable, not to
trigger (i.e. clock) datapath flip-flops!

Ensure all input are synchronous.

Asynchronous input signals can lead to Metastability;

•The violation of setup/hold time may result in the flip-flop entering a metastable state.

•The undetermined value may lead to system failure.

Therefore all incoming asynchronous signal including reset (if asynchronous), must be synchronized to the system clock via a series of flip-flops (two minimum). The first flip-flop can enter metastable state. If this is not resolved within one clock period the second flip-flop could enter metastable
state. This is not very likely, but it is possible. In theory it takes an infinite number of flip-flops in series to guarantee that Metastability will not occur. In practice 3 is the maximum you will ever need.

I do not claim any originality in this article.


"Circuit Design with VHDL" by Volnei A. Pedroni.

‘Fault-tolerant Microprocessors for Space Applications’ by Jiri Gaisler.