Reputation: 115
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
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:
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.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