LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.NUMERIC_STD.ALL; USE work.io_switches_pins.all; ENTITY e_io_switches IS PORT ( rst: IN std_logic; clk: IN std_logic; i_addr: IN std_logic_vector( 0 DOWNTO 0); o_rd_data: OUT std_logic_vector(31 DOWNTO 0); pin_i_switches: IN t_io_switches_pins ); END ENTITY e_io_switches; ARCHITECTURE a_io_switches OF e_io_switches IS CONSTANT c_scale: natural := 50000; CONSTANT c_states: natural := 5; SUBTYPE t_state IS std_logic_vector(31 DOWNTO 0); TYPE t_states IS ARRAY(0 TO c_states - 1) OF t_state; CONSTANT c_state_def: t_state := io_switches_to_slv( c_io_switches_pins_default); CONSTANT c_states_def: t_states := (OTHERS => c_state_def); SIGNAL n_scale: natural RANGE 0 TO c_scale - 1; SIGNAL r_scale: natural RANGE 0 TO c_scale - 1 := 0; SIGNAL n_states: t_states; SIGNAL r_states: t_states := c_states_def; SIGNAL n_debounced: t_state; SIGNAL r_debounced: t_state := c_state_def; SIGNAL n_rot_val: std_logic_vector( 1 DOWNTO 0); SIGNAL r_rot_val: std_logic_vector( 1 DOWNTO 0) := (OTHERS => '0'); SIGNAL r_rot_prev: std_logic_vector( 1 DOWNTO 0) := (OTHERS => '0'); SIGNAL n_rot_cnt: std_logic_vector(31 DOWNTO 0); SIGNAL r_rot_cnt: std_logic_vector(31 DOWNTO 0) := (OTHERS => '0'); BEGIN p_scale: PROCESS(r_scale) BEGIN IF r_scale >= c_scale - 1 THEN n_scale <= 0; ELSE n_scale <= r_scale + 1; END IF; END PROCESS p_scale; p_sample: PROCESS(pin_i_switches, r_scale, r_states) BEGIN IF r_scale = 0 THEN n_states(0) <= io_switches_to_slv(pin_i_switches); FOR i IN 1 TO c_states - 1 LOOP n_states(i) <= r_states(i - 1); END LOOP; ELSE n_states <= r_states; END IF; END PROCESS p_sample; p_debounce: PROCESS(r_states, r_debounced) VARIABLE v_or: t_state; VARIABLE v_and: t_state; BEGIN v_or := r_states(0); v_and := r_states(0); FOR i IN 1 TO c_states - 1 LOOP v_or := v_or OR r_states(i); v_and := v_and AND r_states(i); END LOOP; n_debounced <= (r_debounced AND v_or) OR v_and; END PROCESS p_debounce; p_de_gray: PROCESS(r_debounced) VARIABLE v_debounced: t_io_switches_pins; BEGIN -- de-gray-code rotary inputs v_debounced := io_switches_from_slv(r_debounced); IF v_debounced.rot_b = '1' THEN IF v_debounced.rot_a = '1' THEN n_rot_val <= "00"; ELSE n_rot_val <= "11"; END IF; ELSE IF v_debounced.rot_a = '1' THEN n_rot_val <= "01"; ELSE n_rot_val <= "10"; END IF; END IF; END PROCESS p_de_gray; p_rot_cnt: PROCESS(r_rot_val, r_rot_prev, r_rot_cnt) VARIABLE v_delta: signed(1 DOWNTO 0); BEGIN v_delta := signed(r_rot_val) - signed(r_rot_prev); n_rot_cnt <= std_logic_vector(signed(r_rot_cnt) + v_delta); END PROCESS p_rot_cnt; p_sync: PROCESS(rst, clk) BEGIN IF rst = '1' THEN r_scale <= 0; r_states <= c_states_def; r_debounced <= c_state_def; r_rot_val <= (OTHERS => '0'); r_rot_prev <= (OTHERS => '0'); r_rot_cnt <= (OTHERS => '0'); ELSIF rising_edge(clk) THEN r_scale <= n_scale; r_states <= n_states; r_debounced <= n_debounced; r_rot_val <= n_rot_val; r_rot_prev <= r_rot_val; r_rot_cnt <= n_rot_cnt; END IF; END PROCESS p_sync; p_read: PROCESS(rst, clk) BEGIN IF rst = '1' THEN o_rd_data <= (OTHERS => '0'); ELSIF rising_edge(clk) THEN IF i_addr = "0" THEN o_rd_data <= r_debounced; ELSE o_rd_data <= r_rot_cnt; END IF; END IF; END PROCESS p_read; END ARCHITECTURE a_io_switches;