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; use work.lx_rocon_pkg.all; -- Quadcounter (for IRC) entity qcounter is port ( -- Inputs clk_i : in std_logic; reset_i : in std_logic; a0_i, b0_i : in std_logic; index0_i : in std_logic; -- State reset_index_event_i : in std_logic; reset_ab_error_i : in std_logic; -- Outputs qcount_o : out std_logic_vector (7 downto 0); qcount_index_o : out std_logic_vector (7 downto 0); index_event_o : out std_logic; a_rise_o, a_fall_o : out std_logic; b_rise_o, b_fall_o : out std_logic; ab_event_o : out std_logic; ab_error_o : out std_logic ); end qcounter; architecture behavioral of qcounter is signal last_reset_s : std_logic; signal a_s, b_s : std_logic; signal a_prev_s, b_prev_s : std_logic; signal ab_error_s : std_logic; signal ab_error_int_s : std_logic; signal index_event_s : std_logic; signal index_event_int_s : std_logic; signal index_s : std_logic; signal count_prev_s : std_logic_vector (5 downto 0); signal count_s : std_logic_vector (5 downto 0); signal count_index_prev_s : std_logic_vector (7 downto 0); signal count_index_s : std_logic_vector (7 downto 0); begin dff_a: dff2 port map ( clk_i => clk_i, reset_i => '0', d_i => a0_i, q_o => a_s ); dff_b: dff2 port map ( clk_i => clk_i, reset_i => '0', d_i => b0_i, q_o => b_s ); dff_index: dff2 port map ( clk_i => clk_i, reset_i => '0', d_i => index0_i, q_o => index_s ); qcount_o(0) <= a_s xor b_s; qcount_o(1) <= b_s; qcount_o(7 downto 2) <= count_s; -- qcount_index_o <= count_index_s; -- ab_error_o <= ab_error_int_s; index_event_o <= index_event_int_s; comb_event: process (reset_i, last_reset_s, a_prev_s, b_prev_s, a_s, b_s) begin a_rise_o <= '0'; a_fall_o <= '0'; b_rise_o <= '0'; b_fall_o <= '0'; ab_event_o <= '0'; ab_error_s <= '0'; if reset_i = '0' and last_reset_s = '0' then if ((a_s xor a_prev_s) and (b_s xor b_prev_s)) = '1' then -- forbidden double transition ab_error_s <= '1'; ab_event_o <= '0'; else a_rise_o <= (a_s xor a_prev_s) and a_s; a_fall_o <= (a_s xor a_prev_s) and (not a_s); b_rise_o <= (b_s xor b_prev_s) and b_s; b_fall_o <= (b_s xor b_prev_s) and (not b_s); ab_event_o <= (a_s xor a_prev_s) or (b_s xor b_prev_s); end if; end if; end process; comb_count: process (reset_i, last_reset_s, a_prev_s, b_prev_s, a_s, b_s, index_s, count_prev_s, count_index_prev_s) begin index_event_s <= '0'; if reset_i = '1' or last_reset_s = '1' then count_s <= count_prev_s; count_index_s <= count_index_prev_s; elsif (a_prev_s = '0') and (b_prev_s = '1') and (a_s = '0') and (b_s = '0') then count_s <= count_prev_s + 1; if index_s = '1' then count_index_s(0) <= a_s xor b_s; count_index_s(1) <= b_s; count_index_s(7 downto 2) <= count_prev_s + 1; else count_index_s <= count_index_prev_s; end if; elsif (a_prev_s = '0') and (b_prev_s = '0') and (a_s = '0') and (b_s = '1') then count_s <= count_prev_s - 1; if index_s = '1' then count_index_s(0) <= a_s xor b_s; count_index_s(1) <= b_s; count_index_s(7 downto 2) <= count_prev_s - 1; index_event_s <= '1'; else count_index_s <= count_index_prev_s; end if; else count_s <= count_prev_s; if index_s = '1' then count_index_s(0) <= a_s xor b_s; count_index_s(1) <= b_s; count_index_s(7 downto 2) <= count_prev_s; index_event_s <= '1'; else count_index_s <= count_index_prev_s; end if; end if; end process; seq: process (clk_i) begin -- Reset for qcounter is synchronous and lasts at least one more cycle -- to prevent hazardous states after releasing it if clk_i = '1' and clk_i'event then if reset_i = '1' then count_prev_s <= (others => '0'); count_index_prev_s <= (others => '0'); index_event_int_s <= '0'; ab_error_int_s <= '0'; else count_prev_s <= count_s; count_index_prev_s <= count_index_s; -- if reset_index_event_i = '1' then index_event_int_s <= '0'; else index_event_int_s <= index_event_int_s or index_event_s; end if; -- if reset_ab_error_i = '1' then ab_error_int_s <= '0'; else ab_error_int_s <= ab_error_int_s or ab_error_s; end if; end if; a_prev_s <= a_s; b_prev_s <= b_s; last_reset_s <= reset_i; end if; end process; end behavioral;