I've been tasked with making a state machine following the design requirements shown in the screenshot. I have everything mostly working and the simulation worked as expected. However, when I program the board and observe the states/counter value on the ILA, the counter gets stuck at 7. I am working in Vivado.
I suspect it may have something to do with how the reset for the counter is triggered, however the counter reset between states worked fine in the simulation. I don't see any obvious issues with my code but I'm not sure if I'm missing something or maybe my code works in a simulation but not on hardware for some reason. I've tried changing the counter value, but it didn't change the results on the ILA, I also tried removing the count value from the sensitivity list for the next state process but the count value and state on the ILA remained the same. It seems strange to me that the state occasionally changes from state 1 to 3 and even when it does make it to state 3, the counter still gets stuck at 7. I also tried changing some settings on the ILA but didn't see anything that seemed relevant.
Any insight would be greatly appreciated!
Thanks
--State Machine
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity statemachine is
port(
clock : in std_logic := '0';
reset : in std_logic := '0';
dipswitch : in std_logic := '0'
);
end statemachine;
architecture arch of statemachine is
signal current_state : std_logic_vector(1 downto 0) := "00";
signal next_state : std_logic_vector(1 downto 0) := "00";
signal count_sm : std_logic_vector(3 downto 0) := "0000";
signal counter_reset : std_logic := '0';
signal state_output : std_logic;
--Encoding Scheme
--S0 00
--S1 01
--S2 10
--S3 11
--ILA
COMPONENT ila_0
PORT (
clk : IN STD_LOGIC;
probe0 : IN STD_LOGIC;
probe1 : IN STD_LOGIC_VECTOR(1 DOWNTO 0);
probe2 : IN STD_LOGIC_VECTOR(3 DOWNTO 0)
);
END COMPONENT ;
--4 Bit Counter
component FourBitCounter is
port(
clk : in std_logic;
clr : in std_logic;
count : out std_logic_vector(3 downto 0)
);
end component;
begin
my_ila : ila_0 PORT MAP (
clk => clock,
probe0 => dipswitch,
probe1 => current_state,
probe2 => count_sm
);
Counter : FourBitCounter port map(
clk => clock,
clr => counter_reset,
count => count_sm
);
--State Register
process(clock,reset)
begin
if(clock'event and clock = '1') then
if(reset = '1') then
current_state <= "00";
else
current_state <= next_state;
end if;
end if;
end process;
--Next State Logic
process(current_state,count_sm)
begin
case (current_state) is
when "00" =>
counter_reset <= '1';
if(dipswitch = '1') then
next_state <= "10";
else
next_state <= "01";
end if;
when "01" =>
if(count_sm = "0101") then
next_state <= "11";
counter_reset <= '1';
else
counter_reset <= '0';
end if;
when "10" =>
if(count_sm = "1001") then
next_state <= "11";
counter_reset <= '1';
else
counter_reset <= '0';
end if;
when "11" =>
if(count_sm = "1101") then
next_state <= "00";
counter_reset <= '1';
else
counter_reset <= '0';
end if;
when others =>
next_state <= "00";
end case;
end process;
--Output Logic
process(current_state,count_sm)
begin
case (current_state) is
when "00" =>
state_output <= '0';
when "01" =>
state_output <= '1';
when "10" =>
state_output <= '0';
when "11" =>
state_output <= '1';
when others =>
state_output <= '0';
end case;
end process;
end arch;
--4BitCounter
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity FourBitCounter is
port(
clk : in std_logic := '0';
clr : in std_logic := '0';
count : out std_logic_vector(3 downto 0) := "0000"
);
end FourBitCounter;
architecture arch of FourBitCounter is
signal count_signal : std_logic_vector(3 downto 0) := "0000";
begin
--Counter
process(clk)
begin
if(clk = '1') then
if(clr = '1') then
count_signal <= "0000";
else
count_signal <= count_signal + 1;
end if;
end if;
end process;
count <= count_signal;
end arch;
1 Answer 1
Usually the things I look for when I have errors like this:
Clocking issues -- make sure all processes are clocked appropriately and the sensitivity lists are correct
Make sure all states are defined in blocks so the compiler can't accidentally decide for you:
when "10" =>
if(count_sm = "1001") then
next_state <= "11";
counter_reset <= '1';
else
counter_reset <= '0';
next_state <= "01";
end if;
-
\$\begingroup\$ That's a good tip, I'll keep that in mind for the future. Thanks for the response! \$\endgroup\$AyyBotto– AyyBotto2022年02月04日 21:24:56 +00:00Commented Feb 4, 2022 at 21:24
-
1\$\begingroup\$ I usually assign next_state <= current_state at the top of the next state block to ensure that a missing assignment will not either infer a latch or do something really unexpected. \$\endgroup\$Dan Mills– Dan Mills2022年02月05日 12:10:55 +00:00Commented Feb 5, 2022 at 12:10
if rising_edge(CLK) then
\$\endgroup\$