library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; use ieee.numeric_std.all; -- Quadcounter (for IRC) entity qcounter is port ( clk : in std_logic; reset : in std_logic; a0, b0 : in std_logic; qcount : out std_logic_vector (31 downto 0); a_rise, a_fall, b_rise, b_fall, ab_event: out std_logic; ab_error : out std_logic ); end qcounter; architecture behavioral of qcounter is component dff port ( clk : in std_logic; reset : in std_logic; d : in std_logic; q : out std_logic ); end component; subtype std_logic4 is std_logic_vector (3 downto 0); signal a, b, a_prev, b_prev: std_logic; signal count_prev: std_logic_vector (29 downto 0); signal count: std_logic_vector (29 downto 0); begin dff_a: dff port map ( clk => clk, reset => reset, d => a0, q => a ); dff_b: dff port map ( clk => clk, reset => reset, d => b0, q => b ); qcount(0) <= a xor b; qcount(1) <= b; qcount(31 downto 2) <= count; comb_event: process (reset, a_prev, b_prev, a, b) begin a_rise <= '0'; a_fall <= '0'; b_rise <= '0'; b_fall <= '0'; ab_event <= '0'; ab_error <= '0'; if reset = '0' then if ((a xor a_prev) and (b xor b_prev)) = '1' then -- forbidden double transition ab_error <= '1'; else a_rise <= (a xor a_prev) and a; a_fall <= (a xor a_prev) and not a; b_rise <= (b xor b_prev) and b; b_fall <= (b xor b_prev) and not b; ab_event <= (a xor a_prev) or (b xor b_prev); end if; end if; end process; comb_count: process (reset, a_prev, b_prev, a, b, count, count_prev) begin if reset = '1' then count <= count_prev; elsif (a_prev = '0') and (b_prev = '1') and (a = '0') and (b = '0') then count <= count_prev + 1; elsif (a_prev = '0') and (b_prev = '0') and (a = '0') and (b = '1') then count <= count_prev - 1; else count <= count_prev; end if; end process; seq: process (clk, reset, a, b) begin if reset = '1' then count_prev <= (others => '0'); end if; if clk = '1' and clk'event then if reset = '0' then count_prev <= count; end if; a_prev <= a; b_prev <= b; end if; end process; end behavioral;