State Machines and VHD Coding
State Machines and VHD Coding
This section gives an overview of how to describe state machines with VHDL, it assumes some prior
knowledge of state machine design.
The starting point for most state machine designs is a state flow diagram which shows the various states
and the transitions between them. It can also show any outputs that are generated when the state
machine is in a particular state. An example is shown below:
Example state machine - The state machine is clocked by a signal 'clk' which is not shown on the flow
diagram.
http://www.geocities.com/SiliconValley/Screen/2257/vhdl/state/state.html 4/1/2004
The VHDL & FPGA site - State Machine Design & VHDL Coding Page 2 of 18
l We need to know how the state machine will be clocked - using which signal and on which edge,
rising or falling.
l We need to know how the state machine will be initialized - using which signal, asynchronously
or synchronous to the clock, active high or active low and the initial state itself.
l We need to interpret the state diagram to decide the state transition conditions.
l We need to choose a state assignment (or state encoding) - this will impact the number of flip-
flops required & the speed (i.e. maximum clock frequency that can be employed).
| Back to top |
A state machine advances from one state to another when the particular state transition conditions are
satisfied, synchronous to the state machine's clock input. This can be implemented in a process with the
clock signal in the sensitivity list. The process will only be activated by events on the clock signal
(clk) ensuring all signal and variable changes are synchronized to the clock.
BEGIN
END IF;
All statements enclosed within IF (clk'EVENT AND clk='1') THEN ...END IF; will only
be evaluated when the (clk'EVENT AND clk='1') condition is true, i.e. when a rising edge
occurs on the clk signal. Your synthesis tool should interpret this as positve edge clocked registers.
Alternatively, a WAIT statement could be used, in which case a sensitivity list is not specified:
state_machine : PROCESS
BEGIN
WAIT UNTIL (clk'EVENT AND clk = '0'); -- sync to clk falling edge
All statements enclosed within WAIT UNTIL (clk'EVENT AND clk='0')...END PROCESS
state_machine; will only be evaluated when the (clk'EVENT AND clk='0') condition is
true, i.e. when a falling edge occurs on the clk signal.
http://www.geocities.com/SiliconValley/Screen/2257/vhdl/state/state.html 4/1/2004
The VHDL & FPGA site - State Machine Design & VHDL Coding Page 3 of 18
Your synthesis tool should interpret this as negative edge clocked registers (and will probably need to
invert your clock signal).
Note that in the first of these examples, the rising edge of clk is used to clock the state machine, in the
second the falling edge is used. (see the section on signal attributes for more information).
| Back to top |
Some sort of initialization is usually necessary as the power-up state of the flip-flops may not be defined
or a pushbutton reset may be included on the pcb. For simulation, std_logic type signals and variables
will default to 'U' (uninitialized) if there is no explicit initialization.
Let's look at synchronous initialization first and assume that that the state machine must transition to the
initial state from any other state when the reset input is low. Using the template that we developed
earlier:
BEGIN
ELSE
END IF;
END IF;
The reset signal has not been included in the process sensitivity list, so events on the reset signal
will not activate the process - it's still only the clock that activates the process. The second IF condition
is only evaluated when a rising edge occurs on the clk signal, i.e. synchronous reset. The
state_vector is either a VHDL signal or variable and it is assigned the value idle when the
reset signal is '0' at a rising clock edge. What exactly state_vector and idle are will be
decided by the state assignments that we choose.
Now for the asynchronous initialization. This time the reset signal must be included in the process
sensitivity list as the state machine must respond to events on both the clk signal and the reset signal
- so an event on either signal will activate the process.
http://www.geocities.com/SiliconValley/Screen/2257/vhdl/state/state.html 4/1/2004
The VHDL & FPGA site - State Machine Design & VHDL Coding Page 4 of 18
BEGIN
ELSIF (clk'EVENT AND clk = '1') THEN -- sync to clk rising edge
END IF;
Note that the reset has priority over the clock implicitly due to the fact that the IF statement is
evaluated in sequential order and hence the initialization condition is checked first - if it evaluates to
TRUE the state_vector will be assigned the value idle regardless of the value of clk.
| Back to top |
State transitions
The templates we have developed so far allow us to define where our example state machine will start
from (the initial state is idle ) and when the state transitions will take place (synchronous with the
rising or falling edge of clk). We now need to define the conditions that cause the state transitions to
happen. Examining the example state diagram above we see that :
l The state machine will go to the idle state whenever reset is '0' (i.e. asynchronous).
l It will stay in idle until start is '0' then it will pass to state1.
l From state1, it will pass into state2 if branch is '0', if branch is '1' it will pass into
state4.
l From state2, it will pass into state3.
l From state3, it will pass into state4 if hold is '0', otherwise it will stay in state3.
The generally accepted method of coding a state flow is by using a CASE...WHEN construct with one
WHEN for each state. The transition conditions for each state are described by IF...THEN ...ELSE
statements. The VHDL process will now look like this:
BEGIN
-- state transitions
http://www.geocities.com/SiliconValley/Screen/2257/vhdl/state/state.html 4/1/2004
The VHDL & FPGA site - State Machine Design & VHDL Coding Page 5 of 18
CASE state_vector IS
END CASE;
END IF;
END PROCESS state_machine;
| Back to top |
Note : State encoding is also known as state assignment and the term 'explicit' is sometimes used instead
of 'manual'.
Binary encoding
Using binary encoding, each state is assigned a unique binary number. Since our example has 6 states,
we will require 3 bits to fully encode it and we will choose to assign the value "000" to idle, "001"
to state1, "010" to state2 and so on. There is no strict reason to use this assignment order, but
http://www.geocities.com/SiliconValley/Screen/2257/vhdl/state/state.html 4/1/2004
The VHDL & FPGA site - State Machine Design & VHDL Coding Page 6 of 18
assigning "000" to idle (the initial state) makes sense as the flip-flops inside most types of FPGA
will power-up already cleared (i.e. at logic '0') or will be cleared by their reset input. (this restriction
does not apply to Xilinx FPGAs). The state encodings are explicitly declared as constants, either in the
architecture declarative section or in the process declarative section or in a separate VHDL package -
however declaring them in the architecture declarative section is more usual as they generally need only
be visible inside the architecture where the state machine process resides. If they need to be visible
outside of the architecture (i.e. used by other design entities), then a package can be used.
BEGIN
Gray encoding
This is a form of binary encoding in which only one bit of the state vector changes when moving from
state to state so that the state vector doesn't pass through any intermediate values - important if it's being
decoded asynchronously elsewhere in the FPGA. The states are then known as "adjacent states". The
VHDL code for the state assignments is similar to the binary coding:
BEGIN
Enumerated type
First an enumeration type 'states' is declared whose range of possible values are the names of the
states in the state machine. Then the state vector is declared as a signal of type states:
BEGIN
It is not immediately clear from this exactly how many bits are required to encode all the states (i.e.
exactly how many bits are required for the state vector) and what the state encoding will be. Most
VHDL compilers will correctly synthesise the required number of bits and default to a sequential binary
http://www.geocities.com/SiliconValley/Screen/2257/vhdl/state/state.html 4/1/2004
The VHDL & FPGA site - State Machine Design & VHDL Coding Page 7 of 18
The default state encoding can be overidden by using the enum_encoding attribute:
BEGIN
This will assign the values "000"; to idle, "100" to state1, etc. The state assignment in this
example is gray coded and the synthesis results are the same as the gray encoding example. This
technique could be applied equally well to the binary coding scheme.
The one-hot encoding technique was developed as a consequence of the typical FPGA architecture -
rich in registers but with limited fan-in to each internal logic block. It is sometimes known as state-per-
bit encoding as the state vector has one bit for each state in the state machine. For more information, see
the One-hot state machine & VHDL coding section.
| Back to top |
Some VHDL synthesis tools will allow the state encoding scheme to be selected automatically using a
'synthesis directive' which takes the form of a VHDL attribute. For example, the Metamor compiler will
automatically generate a one-hot encoded state machine if the following code is included:
BEGIN
Refer to the documentation supplied with the VHDL synthesis tool you are using.
| Back to top |
http://www.geocities.com/SiliconValley/Screen/2257/vhdl/state/state.html 4/1/2004
The VHDL & FPGA site - State Machine Design & VHDL Coding Page 8 of 18
So far all the examples have used a single process to describe the state machine. A popular coding style
is to use two processes, a combinatorial process and a synchronous process. In the combinatorial
process, the state transition conditions are described in terms of the present state (and any inputs) and in
the synchronous process the clocking is defined. Using this style for our example state machine (with
asynchronous initialization and explicit binary state encoding) gives :
BEGIN
-- state transitions
CASE present_state IS
http://www.geocities.com/SiliconValley/Screen/2257/vhdl/state/state.html 4/1/2004
The VHDL & FPGA site - State Machine Design & VHDL Coding Page 9 of 18
END CASE;
To implement a synchronous initialization in a two process state machine, just change the synchronous
process as follows:
BEGIN
ELSE
present_state <= next_state; -- ..change state
END IF;
END IF;
END PROCESS sync_proc;
| Back to top |
The CASE statements used in our examples all include the WHEN OTHERS condition which defines the
state machine action when the state vector has a value that is not covered by the state assignments - the
state machine is in an illegal state. This can happen in real-world design due to such things as noise,
power glitches or flip-flop setup and hold violations.
http://www.geocities.com/SiliconValley/Screen/2257/vhdl/state/state.html 4/1/2004
The VHDL & FPGA site - State Machine Design & VHDL Coding Page 10 of 18
The designer can choose to make the state machine 'fault tolerant' by forcing the state machine to a legal
state (usually the initial state) whenever it is in an illegal state using the WHEN OTHERS as follows:
This however consumes a lot more logic resources. If fault recovery is not required then the designer
can choose to define the uncovered values as 'don't care':
This will allow the logic synthesis tool to minimize the state transition equations. Note that there must
be one '-' for each bit in the state vector.
The WHEN OTHERS condition may also be needed for simulation even if all the states have been
assigned - the state vector is usually defined as being a std_logic_vector type, and so each bit in
the state vector has 9 possible values, not just '1' or '0'.
| Back to top |
Most state machines are used to generate other outputs, not just the state vector itself. These other
outputs are generated either from the state vector only (Moore machine) or from a combination of the
state vector and other inputs (Mealy machine).
As an example, we will generate two outputs from our example state machine; out1 will be active high
in state2 and state3 and out2 will be active high in state3 if an additional input, in1, is active
high. The timing is shown below:
http://www.geocities.com/SiliconValley/Screen/2257/vhdl/state/state.html 4/1/2004
The VHDL & FPGA site - State Machine Design & VHDL Coding Page 11 of 18
The output decoding logic introduces an extra propagation delay between the clock edge and the output
signals. Assuming that the rising edge of clk is used to clock the present state registers (i.e. the state
vector) then the clock edge to output delay is as shown below:
http://www.geocities.com/SiliconValley/Screen/2257/vhdl/state/state.html 4/1/2004
The VHDL & FPGA site - State Machine Design & VHDL Coding Page 12 of 18
The total delay from the rising clock edge to when the output changes state is made up of the delay from
the clock edge to when the state vector changes state (Tco) plus the propagation delay in the output
decoding logic (Tpd).
If the state machine has been coded in the single process style, the state vector must be declared as a
signal (so that it's visible outside the process), and then the outputs can be generated using a conditional
signal assignment (WHEN ...ELSE):
If the two process style has been used, the output assignments can be placed inside a separate
combinational process (i.e. a third process), with a signal assignment in each WHEN clause:
BEGIN
-- state transitions
CASE present_state IS
http://www.geocities.com/SiliconValley/Screen/2257/vhdl/state/state.html 4/1/2004
The VHDL & FPGA site - State Machine Design & VHDL Coding Page 13 of 18
END CASE;
This is best described using a multi-process style as the code for the outputs can be kept seperate from
the code for the state vector.
http://www.geocities.com/SiliconValley/Screen/2257/vhdl/state/state.html 4/1/2004
The VHDL & FPGA site - State Machine Design & VHDL Coding Page 14 of 18
BEGIN
-- state transitions
CASE present_state IS
END CASE;
-- output transitions
CASE present_state IS
http://www.geocities.com/SiliconValley/Screen/2257/vhdl/state/state.html 4/1/2004
The VHDL & FPGA site - State Machine Design & VHDL Coding Page 15 of 18
END CASE;
ELSIF (clk'EVENT AND clk = '0') THEN -- sync to clk falling edge..
END IF;
END PROCESS sync_proc;
The main advantage of a state machine implemented in this way, is that the time delay from the clock
http://www.geocities.com/SiliconValley/Screen/2257/vhdl/state/state.html 4/1/2004
The VHDL & FPGA site - State Machine Design & VHDL Coding Page 16 of 18
edge to when the outputs change state is the same as that for the state vector :
However the outputs can only change state when a clock edge occurs.
One disadvantage of this coding style can be seen by examining the output combinatorial process:
Our original specification for the outputs required out1 to go active high in state2, but the above
code snippet seems to indicate that it goes high in state1, but what the code is really "saying" is that
when the state vector changes from state1 to state2, then the signal out1 is assigned the value of
the signal next_out1. We can overcome this slight difficulty by using the next state vector instead of
the present state.
http://www.geocities.com/SiliconValley/Screen/2257/vhdl/state/state.html 4/1/2004
The VHDL & FPGA site - State Machine Design & VHDL Coding Page 17 of 18
This is essentially the same as the previous coding style (and produces the same timing) but avoids the
problem of outputs being specified with the states preceding the one in which they are actually active.
The only change to the code is in the outputs combinatorial process. The next state vector
(next_state)is now included in the sensitivity list instead of the present state vector:
-- output transitions
CASE next_state IS
http://www.geocities.com/SiliconValley/Screen/2257/vhdl/state/state.html 4/1/2004
The VHDL & FPGA site - State Machine Design & VHDL Coding Page 18 of 18
END CASE;
The other difference that can be seen is for the output generation in state3:
The next state vector is generated from the present state vector and the start, branch and hold
inputs - so the code to generate the outputs when the next state vector is state3 isn't qualified with
hold.
http://www.geocities.com/SiliconValley/Screen/2257/vhdl/state/state.html 4/1/2004
The VHDL & FPGA site - One Hot State Machine Design & VHDL Coding Page 1 of 8
This section gives an overview of how to describe one-hot state machines with VHDL, it assumes some
prior knowledge of state machine design. Users should be familiar with the State Machine Design &
VHDL Coding section before going ahead to this section.
A one-hot encoded state machine is a state machine in which there is a bit in the state vector for every
state in the state machine. (eg. a state machine with 17 states will have a 17-bit wide state vector). It is
sometimes known as bit-per-state encoding.
The one-hot encoding technique was developed as a consequence of the typical FPGA architecture -
rich in registers but with limited fan-in to each internal logic macrocell (a CLB in Xilinx-speak). Only
one of the state vector registers is active ('hot') at any one time.
http://www.geocities.com/SiliconValley/Screen/2257/vhdl/state/one-hot.html 4/1/2004
The VHDL & FPGA site - One Hot State Machine Design & VHDL Coding Page 2 of 8
Example state machine - The state machine is clocked by a signal 'clk' which is not shown on the flow
diagram.
| Back to top |
To detect when the state machine is in a particular state only requires that a single bit is tested instead of
the whole state vector as would be the case for a binary-coded state machine. Changing states is simply
a case of changing the currently 'hot' register to 'cold' and setting the next state register to 'hot'. (Note
that 2 bits in the state vector change for every state transition - so caution must be used if the state
vector is decoded asynchronously to generate other outputs.) The logic required to detect the current
state to generate outputs and next state logic is minimal, requiring less combinatorial logic - so allowing
for higher clock frequencies. This is the main reason for using the one-hot structure. Our example state
machine has 6 states, so 6 registers will be required - the disadvantage of one-hot encoding is the larger
quantity of registers that are required.
| Back to top |
One-hot state machines require more flip-flops than a binary-coded state machine, so use them in
devices that are register-rich but have low fan-in to each logic macrocell (e.g. Xilinx FPGAs). They are
generally not useful in CPLDs such as the Xilinx 9500 or CoolRunner families since these have a wide
fan-in to each logic macrocell.
| Back to top |
Soft encoding
Soft encoding a state machine allows the state encoding to be quickly and easily changed. The basic
technique is to declare an enumeration type which has the state names as the set of possible values, then
declare the state vector(s) as signals of that type. The default encoding of the enumeration type is
modified by the attribute "enum_encoding". The state assignments are made by positional association
between the TYPE declaration and the ATTRIBUTE declaration. In our example listing below, idle
takes the value "000001", state1 takes the value "000010" and so on. The rest of the state
machine is coded as normal using a CASE construct. The following code snippet (Listing 1) shows our
example state machine coded as a one-hot state machine using the two-process style:
IMPORTANT!
Not all synthesis tools support the enum_encoding attribute
http://www.geocities.com/SiliconValley/Screen/2257/vhdl/state/one-hot.html 4/1/2004
The VHDL & FPGA site - One Hot State Machine Design & VHDL Coding Page 3 of 8
and some may use a different name for the attribute. Check
your synthesis tool documentation.
BEGIN
-- state transitions
CASE present_state IS
END CASE;
http://www.geocities.com/SiliconValley/Screen/2257/vhdl/state/one-hot.html 4/1/2004
The VHDL & FPGA site - One Hot State Machine Design & VHDL Coding Page 4 of 8
Note the lack of a WHEN OTHERS clause - this will be discussed further in Undefined States.
A further extension of this idea is to replace the state assignments string with a text string that directs
the synthesis tool to produces the required state encoding. For example the Metamor synthesis tool can
produce a one-hot state machine by changing the expression in the attribute specification line to "one
hot". The attribute specification line:
then becomes:
Hard encoding
Hard encoding ensures that a one-hot state machine is always generated, regardless of the synthesis tool
that is being used. This makes it less portable to other targets which might not be register-rich.
The CASE construct can't be used as it will use the entire state vector to make the state-to-state
transition equations, and we need to use only the inputs and the currently 'hot' state. Each state is
considered in turn, using an IF...THEN ...END IF; structure which describes when the state
becomes 'hot' or 'cold'. The VHDL code for the example state machine is:
http://www.geocities.com/SiliconValley/Screen/2257/vhdl/state/one-hot.html 4/1/2004
The VHDL & FPGA site - One Hot State Machine Design & VHDL Coding Page 5 of 8
BEGIN
BEGIN
-- idle
IF ((state_vector(idle) = hot AND start = '1') OR
state_vector(state5) = hot)
THEN
state_vector(idle) <= hot;
ELSE
state_vector(idle) <= cold;
END IF;
-- state 1
IF (state_vector(idle) = hot AND start = '0') THEN
state_vector(state1) <= hot;
ELSE
state_vector(state1) <= cold;
END IF;
-- state 2
IF (state_vector(state1) = hot AND branch = '0') THEN
state_vector(state2) <= hot;
ELSE
state_vector(state2) <= cold;
END IF;
-- state 3
IF (state_vector(state2) = hot OR
(state_vector(state3) = hot AND hold = '1'))
THEN
state_vector(state3) <= hot;
ELSE
state_vector(state3) <= cold;
END IF;
-- state 4
IF ((state_vector(state3) = hot AND hold = '0') OR
(state_vector(state1) = hot AND branch = '1'))
THEN
state_vector(state4) <= hot;
ELSE
state_vector(state4) <= cold;
END IF;
-- state 5
http://www.geocities.com/SiliconValley/Screen/2257/vhdl/state/one-hot.html 4/1/2004
The VHDL & FPGA site - One Hot State Machine Design & VHDL Coding Page 6 of 8
END IF;
| Back to top |
Note that 2 bits of the state vector change for each state transition: the present state goes cold, the next
state goes hot, so be careful when asynchronously decoding the state vector to produce auxiliary
outputs. It may be better to have synchronous outputs.
Because there is one flip-flop per state, some outputs may require a large number of product terms (fan-
in) which defeats the purpose of one-hot encoding. Consider for example an output that is active in the
first 8 states of a state machine with 16 states. With a one-hot coded state machine, this will require 8
product terms, but with a binary coded state machine it may require as little as 1 product term. However,
an output which is valid in only one state may benefit from one-hot encoding as the output is just the
state bit itself.
| Back to top |
Undefined states
One concern that many designers have with one -hot state machines is the large number of undefined
states. A binary-coded version of our example state machine requires a 3 bit state vector, and so the
number of undefined states is:
23 - 6 = 2 undefined states.
The designer can take care of these undefined states using the WHEN OTHERS clause. See the State
Machine Design & VHDL Coding section for more information.
A one-hot coded version of the example state machine however has many more undefined states
because the state vector is 6 bits wide:
26 - 6 = 58 undefined states.
http://www.geocities.com/SiliconValley/Screen/2257/vhdl/state/one-hot.html 4/1/2004
The VHDL & FPGA site - One Hot State Machine Design & VHDL Coding Page 7 of 8
IMPORTANT!
A one-hot state machine is in an illegal state when more than
one of the bits in the state vector is 'hot'.
Using the WHEN OTHERS clause to take care of undefined states may not feasible because of the large
amount of wide fan-in logic that will be generated.
The designer must decide what action should be taken when the state machine finds itself in an illegal /
undefined state - should it go to a particular state? (perhaps the initial state), should it be reset
asynchronously or synchronously? The designer can also decide to take no action on reaching an
undefined state, allowing maximum logic minimisation, but risking a locked-up state machine. The
consequences of these decisions will have far reaching effects on the amount of logic produced.
| Back to top |
One-hot coding is used to increase the maximum clock frequency, so don't let the FPGA routing and
layout cause any unnecessary loss due to excessive routing delays.
l use a global clock buffer for the clock net to ensure low skew and maximum speed.
l place the next state logic in the same CLB as the flip-flop that it feeds ensure low interconnection
delays.
l place the state vector flip-flops in adjacent CLBs with the floorplan tool or by using RLOC
| Back to top |
FPGA Express users have a further alternative to the hard and soft encoding styles described above.
FPGA Express allows the designer to specify either one-hot or binary encoding as an synthesis option.
The ENUM_ENCODING attribute must be left out to allow FPGA Express to choose the state encoding,
just declare the enumeration type and the state vector(s):
-- DON'T USE THESE TWO LINES, ALLOW FPGA EXPRESS TO CHOOSE ENCODING!
--ATTRIBUTE enum_encoding : string;
--ATTRIBUTE enum_encoding OF states: TYPE IS "000001 000010 000100
-- 001000 010000 100000";
http://www.geocities.com/SiliconValley/Screen/2257/vhdl/state/one-hot.html 4/1/2004
The VHDL & FPGA site - One Hot State Machine Design & VHDL Coding Page 8 of 8
BEGIN
.
.
Then in the Synopsys FPGA Express GUI (or the Xilinx Foundation GUI), choose Synthesis ->
Options, and click on the Project Tab of the Options dialog box. Select the encoding style as required.
In the Xilinx Foundation GUI, just choose Synthesis -> Options to see the Options dialog box.
http://www.geocities.com/SiliconValley/Screen/2257/vhdl/state/one-hot.html 4/1/2004