I'm building a counter that counts rising edges from an input channel. I've simplified my design to include two states, one
and two
, where counting is done. For some reason, whenever I try to add 1 to counter_reg
, or try to assign any number at all to it, the signal becomes red with an X in ModelSim. The code and picture of what happens to the signal are provided below.
I have included the IEEE.NUMERIC_STD.ALL, so I should be able to do unsigned addition. I am not sure what is wrong with counter_reg
. Is there anything I'm doing wrong with the counter?
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity photon_counter is
Port ( clk,reset : in STD_LOGIC;
arm,shifter,channel : in STD_LOGIC;
start : in STD_LOGIC);
end photon_counter;
architecture fsm_arch of photon_counter is
type state_type is (idle,zero,one);
type array_type is array (1 downto 0) of UNSIGNED (15 downto 0);
signal state_reg,state_next : state_type;
signal arm_prev,shifter_prev,channel_prev : STD_LOGIC;
signal counter : array_type;
signal counter_reg,counter_next : UNSIGNED (15 downto 0);
begin
--------------------------------------
--State Register
--------------------------------------
process(clk,reset)
begin
if reset='1' then
state_reg <= zero;
counter_reg <= (others => '0');
counter <= (others => (others => '0'));
elsif rising_edge(clk) then
state_reg <= state_next;
counter_reg <= counter_next;
arm_prev <= arm;
shifter_prev <= shifter;
channel_prev <= channel;
end if;
end process;
--------------------------------------
--Next-State Logic/Output Logic
--------------------------------------
process(clk,reset,state_reg,start,counter_reg,shifter_prev,shifter,arm,channel_prev,channel)
begin
--default actions
state_next <= state_reg;
counter_next <= counter_reg;
counter_reg <= counter_reg;
case state_reg is
when idle =>
counter_reg <= (others => '0');
counter <= (others => (others => '0'));
if start = '1' then
state_next <= zero;
end if;
when zero =>
if (shifter = '1') and (shifter_prev = '0') then
state_next <= one;
counter(0) <= counter_reg;
end if;
if (channel = '1') and (channel_prev = '0') then
counter_next <= counter_reg + 1;
end if;
when one =>
if arm = '1' then
state_next <= zero;
counter(1) <= counter_reg;
end if;
if (channel = '1') and (channel_prev = '0') then
counter_reg <= counter_reg + 1;
end if;
end case;
end process;
end fsm_arch;
As shown below, counter_reg
and counter_next
start off with a value of 0 until I try to add 1 to counter_next. The moment channel_prev
rises, both counter_reg
and counter_next
become X (error) and turn red.