I have seen many state machines implemented like this one from Altera:
ARCHITECTURE a OF state_machine IS
TYPE STATE_TYPE IS (s0, s1, s2);
SIGNAL state : STATE_TYPE;
BEGIN
PROCESS (clk, reset)
BEGIN
IF reset = '1' THEN
state <= s0;
ELSIF (clk'EVENT AND clk = '1') THEN
CASE state IS
WHEN ...
An alterantive to that would be this:
ARCHITECTURE a OF state_machine IS
TYPE STATE_TYPE IS (s0, s1, s2);
BEGIN
PROCESS (clk, reset)
VARIABLE state : STATE_TYPE := s0;
BEGIN
IF reset = '1' THEN
state <= s0;
ELSIF (clk'EVENT AND clk = '1') THEN
CASE state IS
WHEN ...
What are the pros (if any) and cons of doing it the alternative way? I have only seen the alternative in one place and I'm guessing there must be some good reason for that.
I like to keep local things local, so if the state information is needed only within the process, I use a variable. In that case, I also like to declare the state type inside the process:
ARCHITECTURE a OF state_machine IS
BEGIN
PROCESS (clk, reset)
TYPE STATE_TYPE IS (s0, s1, s2);
VARIABLE state : STATE_TYPE := s0;
BEGIN
...
In the rare cases where I need to access the state of an FSM from another process (e.g. interactive state machines), I'll use a signal for storing the state.
The signal vs. variable decision if often a matter of taste. Some developers think that variables are evil and will never use them. Others (like me) use them whenever they can to keep local things local. As a bonus, since variables are more lightweight objects than signals, they also simulate faster.