Ril Dank
Ril Dank

Reputation: 115

VHDL 2 process state machine and output initialization

So Altera provides an example of a 2 process state machine a this link.

I kinda like this style, but what I don't understand is that if 'input' stays at '0', the second process is never triggered as the state never changes, and 'output' is therefore never assigned nor initialized... Or is it ?

My understanding is that there need to be a transition on one of the sensitivity list signal ('state' in this example) which could never occur here.

Could someone please clarify what's the deal here ?

Here's the code :

ENTITY state_machine IS
   PORT(
      clk      : IN   STD_LOGIC;
      input    : IN   STD_LOGIC;
      reset    : IN   STD_LOGIC;
      output   : OUT  STD_LOGIC_VECTOR(1 downto 0));
END state_machine;
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 s0=>
               IF input = '1' THEN
                  state <= s1;
               ELSE
                  state <= s0;
               END IF;
            WHEN s1=>
               IF input = '1' THEN
                  state <= s2;
               ELSE
                  state <= s1;
               END IF;
            WHEN s2=>
               IF input = '1' THEN
                  state <= s0;
               ELSE
                  state <= s2;
               END IF;
         END CASE;
      END IF;
   END PROCESS;

   PROCESS (state)
   BEGIN
      CASE state IS
         WHEN s0 =>
            output <= "00";
         WHEN s1 =>
            output <= "01";
         WHEN s2 =>
            output <= "10";
      END CASE;
   END PROCESS;

END a;

EDIT: Just to clarify, my question is: it looks to me that 'output' will be in a undefined state until 'input' transitions to '1'. Isn't that bad practice, considering this is an official example from Altera ? And by the way, what would be the proper way of initializing 'output' here ? With async reset ?

Upvotes: 1

Views: 1446

Answers (1)

Renaud Pacalet
Renaud Pacalet

Reputation: 28945

...it looks to me that 'output' will be in a undefined state until 'input' transitions to '1'.

No (see below). At the beginning of the simulation, output will immediately take value "00", even if the reset is not asserted and there is no transition on input.

Isn't that bad practice, considering this is an official example from Altera ?

No, this code is fine. The state register (state) can be properly initialized, thanks to the reset, and output combinatorialy depends on state. This model will behave as expected, both in simulation and in hardware.

And by the way, what would be the proper way of initializing 'output' here ? With async reset ?

You don't initialize outputs of combinatorials with reset. Resets (asynchronous or synchronous) are used to initialize registers (state, in your example).

Sensitivity lists are just syntactical sugar. A process with sensitivity list is equivalent to the same process, without sensitivity list, and with a wait on <sensitivity-list>; as the last statement. Example:

PROCESS (state)
BEGIN
  CASE state IS
     WHEN s0 =>
        output <= "00";
     WHEN s1 =>
        output <= "01";
     WHEN s2 =>
        output <= "10";
  END CASE;
END PROCESS;

is equivalent to:

PROCESS
BEGIN
  CASE state IS
     WHEN s0 =>
        output <= "00";
     WHEN s1 =>
        output <= "01";
     WHEN s2 =>
        output <= "10";
  END CASE;
  WAIT ON state;
END PROCESS;

So, this process is triggered (as all processes) at the beginning of the simulation, and it assigns a value to output. In your particular case, this value will be "00" because the initial value of state is the leftmost value of its enumerated type, that is, s0. All in all, output is initialized to "UU" (U is the leftmost value of enumerated type std_logic) and, after the very first simulation step (at T=0), it takes value "00".

Note: this code is fine and a good representative of coding for a Moore state machine (not Mealy, as other answers state: the outputs depend only on the current state). But it has (at least) two small problems:

  1. It uses the std_logic resolved type for single-drive signals, which is not a very good idea. std_ulogic and std_ulogic_vector would be much better and much safer.
  2. It uses the names input and output which, while not reserved words of the language, should be avoided: they are the standard input and output streams defined in std.textio.

Upvotes: 2

Related Questions