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
(
- 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
+ -- 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_index_event2_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_o : out std_logic;
+ index_event_o : out std_logic;
+ index_event2_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
- component dff
- port
+
+ 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_int_s : std_logic;
+ signal index_event2_int_s : std_logic;
+ signal index_s : std_logic;
+ signal index_prev_s : std_logic;
+ signal count_prev_s : std_logic_vector (5 downto 0);
+ signal count_s : std_logic_vector (5 downto 0);
+ signal count_out_s : std_logic_vector (7 downto 0);
+ signal count_index_s : std_logic_vector (7 downto 0);
+
+begin
+dff_a: dff3
+ port map
(
- clk : in std_logic;
- reset : in std_logic;
- d : in std_logic;
- q : out std_logic
+ clk_i => clk_i,
+ d_i => a0_i,
+ q_o => a_s
);
- end component;
-subtype std_logic4 is std_logic_vector (3 downto 0);
- signal last_reset: std_logic;
- 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
+ dff_b: dff3
port map
(
- clk => clk,
- reset => '0',
- d => a0,
- q => a
+ clk_i => clk_i,
+ d_i => b0_i,
+ q_o => b_s
);
- dff_b: dff
+dff_index: dff3
port map
(
- clk => clk,
- reset => '0',
- d => b0,
- q => b
+ clk_i => clk_i,
+ d_i => index0_i,
+ q_o => index_s
);
- qcount(0) <= a xor b;
- qcount(1) <= b;
- qcount(31 downto 2) <= count;
-
- comb_event: process (reset, last_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' and last_reset = '0' then
- if ((a xor a_prev) and (b xor b_prev)) = '1' then
+ count_out_s(0) <= a_s xor b_s;
+ count_out_s(1) <= b_s;
+ count_out_s(7 downto 2) <= count_s;
+ --
+ qcount_o <= count_out_s;
+ qcount_index_o <= count_index_s;
+ --
+ ab_error_o <= ab_error_int_s;
+ index_o <= index_s;
+ index_event_o <= index_event_int_s;
+ index_event2_o <= index_event2_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 <= '1';
+ ab_error_s <= '1';
+ ab_event_o <= '0';
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);
+ 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, last_reset, a_prev, b_prev, a, b, count_prev)
- begin
- if reset = '1' or last_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;
+comb_count:
+ process (reset_i, last_reset_s, a_prev_s, b_prev_s, a_s, b_s,
+ index_s, count_prev_s)
+ begin
+
+ if reset_i = '1' or last_reset_s = '1' then
+ count_s <= count_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;
+ 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;
else
- count <= count_prev;
+ count_s <= count_prev_s;
end if;
+
end process;
- seq: process (clk)
- begin
+seq:
+ process
+ variable index_event_v : std_logic;
+ begin
-- Reset for qcounter is synchronous and lasts at least one more cycle
-- to prevent hazardous states after releasing it
- if clk = '1' and clk'event then
- if reset = '0' then
- count_prev <= count;
- else
- count_prev <= (others => '0');
+ wait until clk_i'event and clk_i = '1';
+
+ index_event_v := '0';
+
+ if reset_i = '1' then
+ count_prev_s <= (others => '0');
+ count_index_s <= (others => '0');
+ index_event_int_s <= '0';
+ index_event2_int_s <= '0';
+ ab_error_int_s <= '0';
+ index_prev_s <= '1';
+ else
+
+ if index_s = '1' and index_prev_s = '0' then
+ count_index_s <= count_out_s;
+ index_event_v := '1';
end if;
- a_prev <= a;
- b_prev <= b;
- last_reset <= reset;
+ --
+ index_event_int_s <= (index_event_int_s and not reset_index_event_i) or
+ index_event_v;
+ --
+ index_event2_int_s <= (index_event2_int_s and not reset_index_event2_i) or
+ reset_index_event_i;
+ --
+ ab_error_int_s <= (ab_error_int_s and not reset_ab_error_i) or ab_error_s;
+ --
+ count_prev_s <= count_s;
+ index_prev_s <= index_s;
+
end if;
+
+ a_prev_s <= a_s;
+ b_prev_s <= b_s;
+ last_reset_s <= reset_i;
end process;
end behavioral;