I'm having trouble with a counter update in my FSM. I have a counter being incremented inside a state: the state must change when the counter hits a constant value N. I try to slim down the code to a minimum example.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity int32_ctrlFSM_debug is
port (
clk : in std_logic;
reset : in std_logic;
trigger : in std_logic
);
end int32_ctrlFSM_debug;
architecture arch of int32_ctrlFSM_debug is
type state_type is (state_1, state_2);
constant N : integer := 4;
signal counter_reg : std_logic_vector(N - 1 downto 0);
signal counter_next : std_logic_vector(N - 1 downto 0);
signal state_reg : state_type;
signal state_next : state_type;
begin
-- FSMD state & data registers
process(clk, reset)
begin
if reset = '1' then
state_reg <= state_1;
counter_reg <= (others => '0');
elsif (clk'event and clk = '1') then
state_reg <= state_next;
counter_reg <= counter_next;
end if;
end process;
-- next-state logic & data path
process (state_reg, trigger)
begin
-- default values
state_next <= state_reg;
counter_next <= counter_reg;
case state_reg is
when state_1 =>
if trigger = '1' then
counter_next <= std_logic_vector(unsigned(counter_reg) + 1);
if unsigned(counter_next) = N-1 then
counter_next <= (others => '0');
state_next <= state_2;
end if;
end if;
when state_2 =>
if trigger = '1' then
counter_next <= std_logic_vector(unsigned(counter_reg) + 1);
if unsigned(counter_next) = N-1 then
counter_next <= (others => '0');
state_next <= state_1;
end if;
end if;
end case;
end process;
end arch;
Here a testbench
library ieee;
use ieee.std_logic_1164.all;
entity int32_ctrlFSM_debug_tb is
end int32_ctrlFSM_debug_tb;
architecture tb of int32_ctrlFSM_debug_tb is
component int32_ctrlFSM_debug
port (
clk : in std_logic;
reset : in std_logic;
trigger : in std_logic
);
end component;
signal clk : std_logic;
signal reset : std_logic;
signal trigger : std_logic;
constant TbPeriod : time := 100 ns; -- EDIT Put right period here
signal TbClock : std_logic := '0';
signal TbSimEnded : std_logic := '0';
begin
dut : int32_ctrlFSM_debug
port map (clk => clk,
reset => reset,
trigger => trigger);
-- Clock generation
TbClock <= not TbClock after TbPeriod/2 when TbSimEnded /= '1' else '0';
-- EDIT: Check that clk is really your main clock signal
clk <= TbClock;
stimuli : process
begin
-- EDIT Adapt initialization as needed
trigger <= '0';
-- Reset generation
-- EDIT: Check that reset is really your reset signal
reset <= '1';
wait for 4 * TbPeriod;
wait for 1 * TbPeriod/2;
reset <= '0';
wait for 10 * TbPeriod;
-- Stimuli
wait for 10 * TbPeriod;
-- send 4 rx_done pulses
for i in 1 to 8 loop
trigger <= '1';
wait for 1 * TbPeriod;
trigger <= '0';
wait for 10 * TbPeriod;
end loop;
-- Stop the clock and hence terminate the simulation
TbSimEnded <= '1';
wait;
end process;
end tb;`
The problem is that my counter never starts. Here's a scrrenshot from Xsim (vivado 2018.3).
I am doing all of this (counter_reg and counter_next) in order to avoid latches. Any help would be appreciated.
Andrea