I am trying to make a finite state machine that switches states based on serial input. I need some explanation regarding how my code is executed. I read in a textbook that the section in the process that I have marked "DEFAULT VALUES" is where I should put my default values. However, my signals seem to take on these values whenever I switch states. For example, I set state_next to idle as the default value. Doing this has caused the FSM to continue to jump to idle from other states for no reason.
My other question is clarification in how the whole process for the FSM is executed. When I move from one state to another, is the section before the case statement (the part marked DEFAULT VALUES) supposed to be executed? Or is it only executed if I move from some later state back to idle? When is the DEFAULT VALUES section supposed to be executed?
My code is shown below. Please refer to the "Next-State Logic" section.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity delay_incrementor is
generic ( delay_ports : natural := 3;
width_ports : natural := 3
);
Port ( clk,reset: in STD_LOGIC;
update : in STD_LOGIC;
in_data : in STD_LOGIC_VECTOR (7 downto 0);
led : out STD_LOGIC_VECTOR (2 downto 0);
out_data : out STD_LOGIC_VECTOR (7 downto 0);
d_big,d_mini,d_opo : inout STD_LOGIC_VECTOR (25 downto 0);
w_big,w_mini,w_opo : inout STD_LOGIC_VECTOR (25 downto 0));
end delay_incrementor;
architecture fsm_arch of delay_incrementor is
type state_type is (idle,channel,d_or_w,delay_channel,delay_channel_inc,width_channel,width_channel_inc);
type delay_file_type is array (delay_ports-1 downto 0) of std_logic_vector (25 downto 0);
type width_file_type is array(width_ports-1 downto 0) of std_logic_vector (25 downto 0);
signal d_reg,d_next,d_succ: delay_file_type;
signal w_reg,w_next,w_succ: width_file_type;
signal state_reg,state_next: state_type;
signal which_channel,which_channel_next: natural;
begin
--------------------------------------
--State Register
--------------------------------------
process(clk,reset)
begin
if reset='1' then
state_reg <= idle;
d_reg <= (others => (others => '0'));
w_reg <= (others => (others => '0'));
which_channel <= 0;
elsif (clk='1' and clk'event) then
state_reg <= state_next;
d_reg <= d_next;
w_reg <= w_next;
which_channel <= which_channel_next;
end if;
end process;
--------------------------------------
--Next-State Logic/Output Logic
--------------------------------------
process(state_reg,in_data,d_reg,w_reg,which_channel)
begin
state_next <= idle; --DEFAULT VALUES
d_succ <= d_reg;
w_succ <= w_reg;
which_channel_next <= 0;
case state_reg is
when idle =>
if in_data = "01100011" then --"c"
state_next <= channel;
which_channel_next <= 0;
end if;
when channel =>
if (48 <= unsigned(in_data)) and (unsigned(in_data)<= 57) then
which_channel_next <= (to_integer(unsigned(in_data))-48);
state_next <= d_or_w;
elsif in_data = "00100011" then --"#"
state_next <= idle;
which_channel_next <= which_channel;
end if;
when d_or_w =>
if in_data = "01100100" then --"d"
state_next <= delay_channel;
elsif in_data = "01110111" then --"w"
state_next <= width_channel;
elsif in_data = "00100011" then --"#"
state_next <= idle;
end if;
when delay_channel =>
if in_data = "01101001" then --"i"
state_next <= delay_channel_inc;
elsif in_data = "00100011" then --"#"
state_next <= idle;
end if;
when delay_channel_inc =>
if in_data = "01110101" then --"u"
d_succ(which_channel) <= std_logic_vector(unsigned(d_reg(which_channel))+250);
elsif in_data = "01100100" then --"d"
d_succ(which_channel) <= std_logic_vector(unsigned(d_reg(which_channel))-250);
else
d_succ(which_channel) <= d_reg(which_channel);
end if;
if in_data = "00100011" then --"#"
state_next <= idle;
end if;
when width_channel =>
if in_data = "01101001" then --"i"
state_next <= width_channel_inc;
elsif in_data = "00100011" then --"#"
state_next <= idle;
end if;
when width_channel_inc =>
if in_data = "01110101" then --"u"
w_succ(which_channel) <= std_logic_vector(unsigned(w_reg(which_channel))+250);
elsif in_data = "01100100" then --"d"
w_succ(which_channel) <= std_logic_vector(unsigned(w_reg(which_channel))-250);
else
w_succ(which_channel) <= w_reg(which_channel);
end if;
if in_data = "00100011" then --"#"
state_next <= idle;
end if;
end case;
end process;
process(update,d_reg,w_reg,reset)
begin
if reset='1' then
d_next <= (others => (others =>'0'));
w_next <= (others => (others =>'0'));
elsif (update'event and update='1') then
d_next <= d_succ;
w_next <= w_succ;
else
d_next <= d_reg;
w_next <= w_reg;
end if;
end process;
--------------------------------------
--Output Logic
--------------------------------------
d_big <= d_reg(0);
d_mini <= d_reg(1);
d_opo <= d_reg(2);
w_big <= w_reg(0);
w_mini <= w_reg(1);
w_opo <= w_reg(2);
end fsm_arch;