+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;
+
+entity qcounter is
+ port (
+ clock: in std_logic;
+ reset: in std_logic;
+ a, b: 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
+ subtype std_logic4 is std_logic_vector (3 downto 0);
+ signal a_prev, b_prev: std_logic;
+ signal count: std_logic_vector (29 downto 0)
+ := "000000000000000000000000000000";
+ signal count_next: std_logic_vector (29 downto 0);
+begin
+ qcount(0) <= a_prev xor b_prev;
+ qcount(1) <= b_prev;
+ qcount(31 downto 2) <= count;
+
+ comb_event: process (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 ((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 process;
+
+ comb_count: process (a_prev, b_prev, a, b, count)
+ begin
+ if (a_prev = '1') and (b_prev = '0') and (a = '0') and (b = '0') then
+ count_next <= count + 1;
+ elsif (a_prev = '0') and (b_prev = '0') and (a = '1') and (b = '0') then
+ count_next <= count - 1;
+ else
+ count_next <= count;
+ end if;
+ end process;
+
+ seq: process
+ begin
+ wait until clock'event and clock = '1';
+ if reset = '1' then
+ count <= "000000000000000000000000000000";
+ else
+ count <= count_next;
+ end if;
+ a_prev <= a;
+ b_prev <= b;
+ end process;
+
+end behavioral;