From 5c172eaa03a4140731713050b95a53c5cc52db6b Mon Sep 17 00:00:00 2001 From: Bernhard Urban Date: Sat, 22 May 2010 02:24:19 +0200 Subject: [PATCH] debouncing sys_res_n --- quartus/project_gen.tcl | 17 +++++ src/Makefile | 6 +- src/TODO | 2 + src/calc.vhd | 33 +++++++-- src/debouncing/counter.vhd | 17 +++++ src/debouncing/counter_beh.vhd | 30 ++++++++ src/debouncing/debounce.vhd | 20 ++++++ src/debouncing/debounce_fsm.vhd | 20 ++++++ src/debouncing/debounce_fsm_beh.vhd | 71 +++++++++++++++++++ src/debouncing/debounce_pkg.vhd | 54 ++++++++++++++ src/debouncing/debounce_struct.vhd | 56 +++++++++++++++ src/debouncing/debounce_tb.vhd | 97 ++++++++++++++++++++++++++ src/debouncing/debounce_top.vhd | 13 ++++ src/debouncing/debounce_top_struct.vhd | 90 ++++++++++++++++++++++++ src/debouncing/event_counter.vhd | 17 +++++ src/debouncing/event_counter_beh.vhd | 31 ++++++++ src/debouncing/event_counter_pkg.vhd | 19 +++++ src/debouncing/sync.vhd | 17 +++++ src/debouncing/sync_beh.vhd | 19 +++++ src/debouncing/sync_pkg.vhd | 19 +++++ 20 files changed, 638 insertions(+), 10 deletions(-) create mode 100644 src/debouncing/counter.vhd create mode 100644 src/debouncing/counter_beh.vhd create mode 100644 src/debouncing/debounce.vhd create mode 100644 src/debouncing/debounce_fsm.vhd create mode 100644 src/debouncing/debounce_fsm_beh.vhd create mode 100644 src/debouncing/debounce_pkg.vhd create mode 100644 src/debouncing/debounce_struct.vhd create mode 100644 src/debouncing/debounce_tb.vhd create mode 100644 src/debouncing/debounce_top.vhd create mode 100644 src/debouncing/debounce_top_struct.vhd create mode 100644 src/debouncing/event_counter.vhd create mode 100644 src/debouncing/event_counter_beh.vhd create mode 100644 src/debouncing/event_counter_pkg.vhd create mode 100644 src/debouncing/sync.vhd create mode 100644 src/debouncing/sync_beh.vhd create mode 100644 src/debouncing/sync_pkg.vhd diff --git a/quartus/project_gen.tcl b/quartus/project_gen.tcl index e972811..2f5df6d 100644 --- a/quartus/project_gen.tcl +++ b/quartus/project_gen.tcl @@ -83,6 +83,23 @@ if {$make_assignments} { #gen ip-core set_global_assignment -name VHDL_FILE ../../src/math_pkg.vhd + #debouncing + set_global_assignment -name VHDL_FILE ../../src/debouncing/counter.vhd + set_global_assignment -name VHDL_FILE ../../src/debouncing/counter_beh.vhd + set_global_assignment -name VHDL_FILE ../../src/debouncing/debounce.vhd + set_global_assignment -name VHDL_FILE ../../src/debouncing/debounce_fsm.vhd + set_global_assignment -name VHDL_FILE ../../src/debouncing/debounce_fsm_beh.vhd + set_global_assignment -name VHDL_FILE ../../src/debouncing/debounce_pkg.vhd + set_global_assignment -name VHDL_FILE ../../src/debouncing/debounce_struct.vhd + set_global_assignment -name VHDL_FILE ../../src/debouncing/debounce_tb.vhd + set_global_assignment -name VHDL_FILE ../../src/debouncing/debounce_top.vhd + set_global_assignment -name VHDL_FILE ../../src/debouncing/debounce_top_struct.vhd + set_global_assignment -name VHDL_FILE ../../src/debouncing/event_counter.vhd + set_global_assignment -name VHDL_FILE ../../src/debouncing/event_counter_beh.vhd + set_global_assignment -name VHDL_FILE ../../src/debouncing/event_counter_pkg.vhd + set_global_assignment -name VHDL_FILE ../../src/debouncing/sync.vhd + set_global_assignment -name VHDL_FILE ../../src/debouncing/sync_beh.vhd + set_global_assignment -name VHDL_FILE ../../src/debouncing/sync_pkg.vhd #pin mapping/system set_location_assignment PIN_N3 -to sys_clk diff --git a/src/Makefile b/src/Makefile index 10f5e59..a09058a 100644 --- a/src/Makefile +++ b/src/Makefile @@ -68,12 +68,12 @@ $(D_BEHSIM)/modelsim.ini: $(D_BEHSIM)/$(WORK)/%/_primary.dat: %.vhd $(D_BEHSIM)/modelsim.ini @echo " CC $<" - @cd $(D_BEHSIM); \ - vcom -work $(WORK) $(MPWD)/$< + cd $(D_BEHSIM); \ + vcom -cover bcest -work $(WORK) $(MPWD)/$< beh_%: $(D_BEHSIM)/$(WORK)/beh_%_tb/_primary.dat beh_%_tb.do behsim cd $(D_BEHSIM); \ - vsim "work.$@_tb(sim)" -f /dev/null -do $(MPWD)/$@_tb.do + vsim -coverage "work.$@_tb(sim)" -f /dev/null -do $(MPWD)/$@_tb.do #postsim postsim: $(POST_VHO) $(POST_SDO) diff --git a/src/TODO b/src/TODO index 3a619e9..e9df3f0 100644 --- a/src/TODO +++ b/src/TODO @@ -13,6 +13,8 @@ o vorteil: man kann auf der taste drauf bleiben und man kann keine zahlen mehr mit den coursertasten eingeben +- uart rx oversampling, uart rx synchronizen (vlg. debouncing/sync*.vhd) + == low prio == - mehr testfaelle fuer alu/scanner/parser - parser refactor diff --git a/src/calc.vhd b/src/calc.vhd index 41250e1..cdee994 100644 --- a/src/calc.vhd +++ b/src/calc.vhd @@ -6,6 +6,8 @@ use work.textmode_vga_component_pkg.all; use work.textmode_vga_pkg.all; use work.textmode_vga_platform_dependent_pkg.all; use work.ps2_keyboard_controller_pkg.all; +use work.debounce_pkg.all; +use work.sync_pkg.all; entity calc is port ( @@ -55,6 +57,8 @@ architecture top of calc is signal p_finished : std_logic; -- parser/scanner signal do_it, finished : std_logic; + -- debouncing + signal sys_res_n_sync : std_logic; begin -- vga/ipcore textmode_vga_inst : entity work.textmode_vga(struct) @@ -65,12 +69,12 @@ begin ) port map ( sys_clk => sys_clk, - sys_res_n => sys_res_n, + sys_res_n => sys_res_n_sync, command => command, command_data => command_data, free => free, vga_clk => vga_clk, - vga_res_n => sys_res_n, + vga_res_n => sys_res_n_sync, vsync_n => vsync_n, hsync_n => hsync_n, r => r, @@ -89,7 +93,7 @@ begin display_inst : entity work.display(beh) port map ( sys_clk => sys_clk, - sys_res_n => sys_res_n, + sys_res_n => sys_res_n_sync, -- history d_new_eingabe => d_new_eingabe, d_new_result => d_new_result, @@ -109,7 +113,7 @@ begin history_inst : entity work.history(beh) port map ( sys_clk => sys_clk, - sys_res_n => sys_res_n, + sys_res_n => sys_res_n_sync, -- scanner s_char => s_char, s_take => s_take, @@ -138,7 +142,7 @@ begin parser_inst : entity work.parser(beh) port map ( sys_clk => sys_clk, - sys_res_n => sys_res_n, + sys_res_n => sys_res_n_sync, -- history p_rget => p_rget, p_rdone => p_rdone, @@ -156,7 +160,7 @@ begin scanner_inst : entity work.scanner(beh) port map ( sys_clk => sys_clk, - sys_res_n => sys_res_n, + sys_res_n => sys_res_n_sync, -- ps/2 new_data => new_data, data => data, @@ -178,12 +182,27 @@ begin ) port map ( sys_clk => sys_clk, - sys_res_n => sys_res_n, + sys_res_n => sys_res_n_sync, -- scanner new_data => new_data, data => data, ps2_clk => ps2_clk, ps2_data => ps2_data ); + + -- debouncer fuer sys_res_n + sys_res_n_debounce_inst : debounce + generic map ( + CLK_FREQ => 33330000, + TIMEOUT => 1 ms, + RESET_VALUE => '1', + SYNC_STAGES => 2 + ) + port map ( + sys_clk => sys_clk, + sys_res_n => '1', + data_in => sys_res_n, + data_out => sys_res_n_sync + ); end architecture top; diff --git a/src/debouncing/counter.vhd b/src/debouncing/counter.vhd new file mode 100644 index 0000000..1aac4c3 --- /dev/null +++ b/src/debouncing/counter.vhd @@ -0,0 +1,17 @@ +library ieee; +use ieee.std_logic_1164.all; +use work.math_pkg.all; + +entity counter is + generic + ( + CNT_MAX : integer range 2 to integer'high + ); + port + ( + sys_clk : in std_logic; + sys_res_n : in std_logic; + clear_cnt : in std_logic; + cnt : out std_logic_vector(log2c(CNT_MAX) - 1 downto 0) + ); +end entity counter; diff --git a/src/debouncing/counter_beh.vhd b/src/debouncing/counter_beh.vhd new file mode 100644 index 0000000..75b711c --- /dev/null +++ b/src/debouncing/counter_beh.vhd @@ -0,0 +1,30 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.math_pkg.all; + +architecture beh of counter is + signal cnt_int, cnt_next : integer range 0 to CNT_MAX; +begin + cnt <= std_logic_vector(to_unsigned(cnt_int, log2c(CNT_MAX))); + + process(sys_clk, sys_res_n) + begin + if sys_res_n = '0' then + cnt_int <= 0; + elsif rising_edge(sys_clk) then + cnt_int <= cnt_next; + end if; + end process; + + process(cnt_int, clear_cnt) + begin + cnt_next <= cnt_int; + + if clear_cnt = '1' then + cnt_next <= 0; + elsif cnt_int < CNT_MAX then + cnt_next <= cnt_int + 1; + end if; + end process; +end architecture beh; diff --git a/src/debouncing/debounce.vhd b/src/debouncing/debounce.vhd new file mode 100644 index 0000000..79a8d26 --- /dev/null +++ b/src/debouncing/debounce.vhd @@ -0,0 +1,20 @@ +library ieee; +use ieee.std_logic_1164.all; + +entity debounce is + generic + ( + CLK_FREQ : integer; + TIMEOUT : time range 100 us to 100 ms := 1 ms; + RESET_VALUE : std_logic := '0'; + SYNC_STAGES : integer range 2 to integer'high + ); + port + ( + sys_clk : in std_logic; + sys_res_n : in std_logic; + + data_in : in std_logic; + data_out : out std_logic + ); +end entity debounce; diff --git a/src/debouncing/debounce_fsm.vhd b/src/debouncing/debounce_fsm.vhd new file mode 100644 index 0000000..dbc22b9 --- /dev/null +++ b/src/debouncing/debounce_fsm.vhd @@ -0,0 +1,20 @@ +library ieee; +use ieee.std_logic_1164.all; +use work.math_pkg.all; + +entity debounce_fsm is + generic + ( + RESET_VALUE : std_logic; + CNT_MAX : integer range 2 to integer'high + ); + port + ( + sys_clk : in std_logic; + sys_res_n : in std_logic; + i : in std_logic; + cnt : in std_logic_vector(log2c(CNT_MAX) - 1 downto 0); + clear_cnt : out std_logic; + o : out std_logic + ); +end entity debounce_fsm; diff --git a/src/debouncing/debounce_fsm_beh.vhd b/src/debouncing/debounce_fsm_beh.vhd new file mode 100644 index 0000000..f30d43b --- /dev/null +++ b/src/debouncing/debounce_fsm_beh.vhd @@ -0,0 +1,71 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +architecture beh of debounce_fsm is + type DEBOUNCE_FSM_STATE_TYPE is + (IDLE0, TIMEOUT0, IDLE1, TIMEOUT1); + signal debounce_fsm_state, debounce_fsm_state_next : DEBOUNCE_FSM_STATE_TYPE; +begin + next_state : process(debounce_fsm_state, i, cnt) + begin + debounce_fsm_state_next <= debounce_fsm_state; + case debounce_fsm_state is + when IDLE0 => + if i = '1' then + debounce_fsm_state_next <= TIMEOUT0; + end if; + when TIMEOUT0 => + if i = '0' then + debounce_fsm_state_next <= IDLE0; + elsif to_integer(unsigned(cnt)) = CNT_MAX then + debounce_fsm_state_next <= IDLE1; + end if; + when IDLE1 => + if i = '0' then + debounce_fsm_state_next <= TIMEOUT1; + end if; + when TIMEOUT1 => + if i = '1' then + debounce_fsm_state_next <= IDLE1; + elsif to_integer(unsigned(cnt)) = CNT_MAX then + debounce_fsm_state_next <= IDLE0; + end if; + end case; + end process next_state; + + output : process(debounce_fsm_state) + begin + o <= RESET_VALUE; + clear_cnt <= '1'; + + case debounce_fsm_state is + when IDLE0 => + o <= '0'; + when TIMEOUT0 => + o <= '0'; + clear_cnt <= '0'; + when IDLE1 => + o <= '1'; + when TIMEOUT1 => + o <= '1'; + clear_cnt <= '0'; + end case; + end process output; + + assert RESET_VALUE = '0' or RESET_VALUE = '1' report + "RESET_VALUE may only be 0 or 1!" severity failure; + + sync : process(sys_clk, sys_res_n) + begin + if sys_res_n = '0' then + if RESET_VALUE = '0' then + debounce_fsm_state <= IDLE0; + else + debounce_fsm_state <= IDLE1; + end if; + elsif rising_edge(sys_clk) then + debounce_fsm_state <= debounce_fsm_state_next; + end if; + end process sync; +end architecture beh; diff --git a/src/debouncing/debounce_pkg.vhd b/src/debouncing/debounce_pkg.vhd new file mode 100644 index 0000000..1368846 --- /dev/null +++ b/src/debouncing/debounce_pkg.vhd @@ -0,0 +1,54 @@ +library ieee; +use ieee.std_logic_1164.all; +use work.math_pkg.all; + +package debounce_pkg is + component debounce_fsm is + generic + ( + RESET_VALUE : std_logic; + CNT_MAX : integer range 2 to integer'high + ); + port + ( + sys_clk : in std_logic; + sys_res_n : in std_logic; + i : in std_logic; + cnt : in std_logic_vector(log2c(CNT_MAX) - 1 downto 0); + clear_cnt : out std_logic; + o : out std_logic + ); + end component debounce_fsm; + + component counter is + generic + ( + CNT_MAX : integer range 2 to integer'high + ); + port + ( + sys_clk : in std_logic; + sys_res_n : in std_logic; + clear_cnt : in std_logic; + cnt : out std_logic_vector(log2c(CNT_MAX) - 1 downto 0) + ); + end component counter; + + component debounce is + generic + ( + CLK_FREQ : integer; + TIMEOUT : time range 100 us to 100 ms := 1 ms; + RESET_VALUE : std_logic := '0'; + SYNC_STAGES : integer range 2 to integer'high + ); + port + ( + sys_clk : in std_logic; + sys_res_n : in std_logic; + + data_in : in std_logic; + data_out : out std_logic + ); + end component debounce; +end package debounce_pkg; diff --git a/src/debouncing/debounce_struct.vhd b/src/debouncing/debounce_struct.vhd new file mode 100644 index 0000000..5e3684c --- /dev/null +++ b/src/debouncing/debounce_struct.vhd @@ -0,0 +1,56 @@ +library ieee; +use ieee.std_logic_1164.all; +use work.sync_pkg.all; +use work.debounce_pkg.all; +use work.math_pkg.all; + +architecture struct of debounce is + constant CLK_PERIOD : time := 1E9 / CLK_FREQ * 1 ns; + constant CNT_MAX : integer := TIMEOUT / CLK_PERIOD; + signal data_sync : std_logic; + signal clear_cnt : std_logic; + signal cnt : std_logic_vector(log2c(CNT_MAX) - 1 downto 0); +begin + sync_inst : sync + generic map + ( + SYNC_STAGES => SYNC_STAGES, + RESET_VALUE => RESET_VALUE + ) + port map + ( + sys_clk => sys_clk, + sys_res_n => sys_res_n, + data_in => data_in, + data_out => data_sync + ); + + fsm_inst : debounce_fsm + generic map + ( + RESET_VALUE => RESET_VALUE, + CNT_MAX => CNT_MAX + ) + port map + ( + sys_clk => sys_clk, + sys_res_n => sys_res_n, + i => data_sync, + o => data_out, + clear_cnt => clear_cnt, + cnt => cnt + ); + + counter_inst : counter + generic map + ( + CNT_MAX => CNT_MAX + ) + port map + ( + sys_clk => sys_clk, + sys_res_n => sys_res_n, + clear_cnt => clear_cnt, + cnt => cnt + ); +end architecture struct; diff --git a/src/debouncing/debounce_tb.vhd b/src/debouncing/debounce_tb.vhd new file mode 100644 index 0000000..ce4744c --- /dev/null +++ b/src/debouncing/debounce_tb.vhd @@ -0,0 +1,97 @@ +library ieee; +use ieee.std_logic_1164.all; + +entity debounce_tb is +end entity debounce_tb; + +architecture sim of debounce_tb is + component debounce_top is + port + ( + sys_clk : in std_logic; + sys_res_n : in std_logic; + btn_a : in std_logic; + seg_a : out std_logic_vector(6 downto 0); + seg_b : out std_logic_vector(6 downto 0) + ); + end component debounce_top; + + signal sys_clk, sys_res_n : std_logic; + signal btn_a : std_logic; + signal seg_a, seg_b : std_logic_vector(6 downto 0); + signal stop : boolean := false; +begin + uut : debounce_top + port map + ( + sys_clk => sys_clk, + sys_res_n => sys_res_n, + btn_a => btn_a, + seg_a => seg_a, + seg_b => seg_b + ); + + process + begin + sys_clk <= '0'; + wait for 15 ns; + sys_clk <= '1'; + if stop = true then + wait; + end if; + wait for 15 ns; + end process; + + process + begin + sys_res_n <= '0'; + btn_a <= '1'; + wait for 100 ns; + sys_res_n <= '1'; + wait for 2 ms; + btn_a <= '0'; + wait for 100 us; + btn_a <= '1'; + wait for 50 us; + btn_a <= '0'; + wait for 150 us; + btn_a <= '1'; + wait for 25 us; + btn_a <= '0'; + wait for 175 us; + btn_a <= '1'; + wait for 1 us; + btn_a <= '0'; + wait for 2 ms; + btn_a <= '1'; + wait for 100 us; + btn_a <= '0'; + wait for 50 us; + btn_a <= '1'; + wait for 150 us; + btn_a <= '0'; + wait for 25 us; + btn_a <= '1'; + wait for 175 us; + btn_a <= '0'; + wait for 1 us; + btn_a <= '1'; + wait for 2 ms; + btn_a <= '0'; + wait for 100 us; + btn_a <= '1'; + wait for 50 us; + btn_a <= '0'; + wait for 150 us; + btn_a <= '1'; + wait for 25 us; + btn_a <= '0'; + wait for 175 us; + btn_a <= '1'; + wait for 1 us; + btn_a <= '0'; + wait for 2 ms; + stop <= true; + wait; + end process; +end architecture sim; diff --git a/src/debouncing/debounce_top.vhd b/src/debouncing/debounce_top.vhd new file mode 100644 index 0000000..0152c5c --- /dev/null +++ b/src/debouncing/debounce_top.vhd @@ -0,0 +1,13 @@ +library ieee; +use ieee.std_logic_1164.all; + +entity debounce_top is + port + ( + sys_clk : in std_logic; + sys_res_n : in std_logic; + btn_a : in std_logic; + seg_a : out std_logic_vector(6 downto 0); + seg_b : out std_logic_vector(6 downto 0) + ); +end entity debounce_top; diff --git a/src/debouncing/debounce_top_struct.vhd b/src/debouncing/debounce_top_struct.vhd new file mode 100644 index 0000000..3d1bcb8 --- /dev/null +++ b/src/debouncing/debounce_top_struct.vhd @@ -0,0 +1,90 @@ +library ieee; +use ieee.std_logic_1164.all; +use work.debounce_pkg.all; +use work.sync_pkg.all; +use work.event_counter_pkg.all; + +architecture struct of debounce_top is + constant CLK_FREQ : integer := 33330000; + constant TIMEOUT : time := 1 ms; + constant RES_N_DEFAULT_VALUE : std_logic := '1'; + constant SYNC_STAGES : integer := 2; + constant BTN_A_RESET_VALUE : std_logic := '1'; + constant EVENT_CNT_WIDTH : integer := 8; + + signal sys_res_n_sync, btn_a_sync : std_logic; + signal event_cnt : std_logic_vector(EVENT_CNT_WIDTH - 1 downto 0); + + function to_segs(value : in std_logic_vector(3 downto 0)) return std_logic_vector is + begin + case value is + when x"0" => return "1000000"; + when x"1" => return "1111001"; + when x"2" => return "0100100"; + when x"3" => return "0110000"; + when x"4" => return "0011001"; + when x"5" => return "0010010"; + when x"6" => return "0000010"; + when x"7" => return "1111000"; + when x"8" => return "0000000"; + when x"9" => return "0010000"; + when x"A" => return "0001000"; + when x"B" => return "0000011"; + when x"C" => return "1000110"; + when x"D" => return "0100001"; + when x"E" => return "0000110"; + when x"F" => return "0001110"; + when others => return "1111111"; + end case; + end function; +begin + sys_res_n_debounce_inst : debounce + generic map + ( + CLK_FREQ => CLK_FREQ, + TIMEOUT => TIMEOUT, + RESET_VALUE => RES_N_DEFAULT_VALUE, + SYNC_STAGES => SYNC_STAGES + ) + port map + ( + sys_clk => sys_clk, + sys_res_n => '1', + data_in => sys_res_n, + data_out => sys_res_n_sync + ); + + btn_a_debounce_inst : debounce + generic map + ( + CLK_FREQ => CLK_FREQ, + TIMEOUT => TIMEOUT, + RESET_VALUE => BTN_A_RESET_VALUE, + SYNC_STAGES => SYNC_STAGES + ) + port map + ( + sys_clk => sys_clk, + sys_res_n => sys_res_n_sync, + data_in => btn_a, + data_out => btn_a_sync + ); + + event_cnt_inst : event_counter + generic map + ( + CNT_WIDTH => EVENT_CNT_WIDTH, + RESET_VALUE => BTN_A_RESET_VALUE + ) + port map + ( + sys_clk => sys_clk, + sys_res_n => sys_res_n_sync, + sense => btn_a_sync, + cnt => event_cnt + ); + + seg_a <= to_segs(event_cnt(3 downto 0)); + seg_b <= to_segs(event_cnt(7 downto 4)); + +end architecture struct; diff --git a/src/debouncing/event_counter.vhd b/src/debouncing/event_counter.vhd new file mode 100644 index 0000000..9d5aadc --- /dev/null +++ b/src/debouncing/event_counter.vhd @@ -0,0 +1,17 @@ +library ieee; +use ieee.std_logic_1164.all; + +entity event_counter is + generic + ( + CNT_WIDTH : integer range 4 to integer'high; + RESET_VALUE : std_logic + ); + port + ( + sys_clk : in std_logic; + sys_res_n : in std_logic; + sense : in std_logic; + cnt : out std_logic_vector(CNT_WIDTH - 1 downto 0) + ); +end entity event_counter; diff --git a/src/debouncing/event_counter_beh.vhd b/src/debouncing/event_counter_beh.vhd new file mode 100644 index 0000000..9d7b8b8 --- /dev/null +++ b/src/debouncing/event_counter_beh.vhd @@ -0,0 +1,31 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +architecture beh of event_counter is + signal sense_old, sense_old_next : std_logic; + signal cnt_int, cnt_next : std_logic_vector(CNT_WIDTH - 1 downto 0); +begin + cnt <= cnt_int; + + process(sys_clk, sys_res_n) + begin + if sys_res_n = '0' then + cnt_int <= (others => '0'); + sense_old <= RESET_VALUE; + elsif rising_edge(sys_clk) then + cnt_int <= cnt_next; + sense_old <= sense_old_next; + end if; + end process; + + process(cnt_int, sense, sense_old) + begin + sense_old_next <= sense; + cnt_next <= cnt_int; + + if sense_old /= sense and sense = '0' then + cnt_next <= std_logic_vector(unsigned(cnt_int) + 1); + end if; + end process; +end architecture beh; diff --git a/src/debouncing/event_counter_pkg.vhd b/src/debouncing/event_counter_pkg.vhd new file mode 100644 index 0000000..3a2b36d --- /dev/null +++ b/src/debouncing/event_counter_pkg.vhd @@ -0,0 +1,19 @@ +library ieee; +use ieee.std_logic_1164.all; + +package event_counter_pkg is + component event_counter is + generic + ( + CNT_WIDTH : integer range 4 to integer'high; + RESET_VALUE : std_logic + ); + port + ( + sys_clk : in std_logic; + sys_res_n : in std_logic; + sense : in std_logic; + cnt : out std_logic_vector(CNT_WIDTH - 1 downto 0) + ); + end component event_counter; +end package event_counter_pkg; diff --git a/src/debouncing/sync.vhd b/src/debouncing/sync.vhd new file mode 100644 index 0000000..8515bd6 --- /dev/null +++ b/src/debouncing/sync.vhd @@ -0,0 +1,17 @@ +library ieee; +use ieee.std_logic_1164.all; + +entity sync is + generic + ( + SYNC_STAGES : integer range 2 to integer'high; + RESET_VALUE : std_logic + ); + port + ( + sys_clk : in std_logic; + sys_res_n : in std_logic; + data_in : in std_logic; + data_out : out std_logic + ); +end entity sync; diff --git a/src/debouncing/sync_beh.vhd b/src/debouncing/sync_beh.vhd new file mode 100644 index 0000000..826bb12 --- /dev/null +++ b/src/debouncing/sync_beh.vhd @@ -0,0 +1,19 @@ +library ieee; +use ieee.std_logic_1164.all; + +architecture beh of sync is + signal sync : std_logic_vector(1 to SYNC_STAGES); +begin + process(sys_clk, sys_res_n) + begin + if sys_res_n = '0' then + sync <= (others => RESET_VALUE); + elsif rising_edge(sys_clk) then + sync(1) <= data_in; + for i in 2 to SYNC_STAGES loop + sync(i) <= sync(i - 1); + end loop; + end if; + end process; + data_out <= sync(SYNC_STAGES); +end architecture beh; diff --git a/src/debouncing/sync_pkg.vhd b/src/debouncing/sync_pkg.vhd new file mode 100644 index 0000000..cf98e57 --- /dev/null +++ b/src/debouncing/sync_pkg.vhd @@ -0,0 +1,19 @@ +library ieee; +use ieee.std_logic_1164.all; + +package sync_pkg is + component sync is + generic + ( + SYNC_STAGES : integer range 2 to integer'high; + RESET_VALUE : std_logic + ); + port + ( + sys_clk : in std_logic; + sys_res_n : in std_logic; + data_in : in std_logic; + data_out : out std_logic + ); + end component sync; +end package sync_pkg; -- 2.25.1