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.