From ed91912ad97514ef90b8c86a79e53bf2b0640d4f Mon Sep 17 00:00:00 2001 From: Bernhard Urban Date: Fri, 26 Mar 2010 20:00:20 +0100 Subject: [PATCH] debouncing example --- debouncing/mjl_stratix/db/mjl_stratix.db_info | 3 + debouncing/mjl_stratix/mjl_stratix.qpf | 30 ++++++ debouncing/mjl_stratix/mjl_stratix.qsf | 92 ++++++++++++++++++ debouncing/prj/create_project.cmd | 4 + debouncing/prj/create_project.tcl | 87 +++++++++++++++++ debouncing/src/counter.vhd | 17 ++++ debouncing/src/counter_beh.vhd | 30 ++++++ debouncing/src/debounce.vhd | 20 ++++ debouncing/src/debounce_fsm.vhd | 20 ++++ debouncing/src/debounce_fsm_beh.vhd | 71 ++++++++++++++ debouncing/src/debounce_pkg.vhd | 54 +++++++++++ debouncing/src/debounce_struct.vhd | 56 +++++++++++ debouncing/src/debounce_tb.vhd | 97 +++++++++++++++++++ debouncing/src/debounce_top.vhd | 13 +++ debouncing/src/debounce_top_struct.vhd | 90 +++++++++++++++++ debouncing/src/event_counter.vhd | 17 ++++ debouncing/src/event_counter_beh.vhd | 31 ++++++ debouncing/src/event_counter_pkg.vhd | 19 ++++ debouncing/src/math_pkg.vhd | 53 ++++++++++ debouncing/src/sync.vhd | 17 ++++ debouncing/src/sync_beh.vhd | 19 ++++ debouncing/src/sync_pkg.vhd | 19 ++++ 22 files changed, 859 insertions(+) create mode 100644 debouncing/mjl_stratix/db/mjl_stratix.db_info create mode 100644 debouncing/mjl_stratix/mjl_stratix.qpf create mode 100644 debouncing/mjl_stratix/mjl_stratix.qsf create mode 100644 debouncing/prj/create_project.cmd create mode 100644 debouncing/prj/create_project.tcl create mode 100644 debouncing/src/counter.vhd create mode 100644 debouncing/src/counter_beh.vhd create mode 100644 debouncing/src/debounce.vhd create mode 100644 debouncing/src/debounce_fsm.vhd create mode 100644 debouncing/src/debounce_fsm_beh.vhd create mode 100644 debouncing/src/debounce_pkg.vhd create mode 100644 debouncing/src/debounce_struct.vhd create mode 100644 debouncing/src/debounce_tb.vhd create mode 100644 debouncing/src/debounce_top.vhd create mode 100644 debouncing/src/debounce_top_struct.vhd create mode 100644 debouncing/src/event_counter.vhd create mode 100644 debouncing/src/event_counter_beh.vhd create mode 100644 debouncing/src/event_counter_pkg.vhd create mode 100644 debouncing/src/math_pkg.vhd create mode 100644 debouncing/src/sync.vhd create mode 100644 debouncing/src/sync_beh.vhd create mode 100644 debouncing/src/sync_pkg.vhd diff --git a/debouncing/mjl_stratix/db/mjl_stratix.db_info b/debouncing/mjl_stratix/db/mjl_stratix.db_info new file mode 100644 index 0000000..9eab77b --- /dev/null +++ b/debouncing/mjl_stratix/db/mjl_stratix.db_info @@ -0,0 +1,3 @@ +Quartus_Version = Version 9.1 Build 222 10/21/2009 SJ Full Version +Version_Index = 184606208 +Creation_Time = Fri Mar 26 10:23:27 2010 diff --git a/debouncing/mjl_stratix/mjl_stratix.qpf b/debouncing/mjl_stratix/mjl_stratix.qpf new file mode 100644 index 0000000..4721af9 --- /dev/null +++ b/debouncing/mjl_stratix/mjl_stratix.qpf @@ -0,0 +1,30 @@ +# -------------------------------------------------------------------------- # +# +# Copyright (C) 1991-2009 Altera Corporation +# Your use of Altera Corporation's design tools, logic functions +# and other software and tools, and its AMPP partner logic +# functions, and any output files from any of the foregoing +# (including device programming or simulation files), and any +# associated documentation or information are expressly subject +# to the terms and conditions of the Altera Program License +# Subscription Agreement, Altera MegaCore Function License +# Agreement, or other applicable license agreement, including, +# without limitation, that your use is for the sole purpose of +# programming logic devices manufactured by Altera and sold by +# Altera or its authorized distributors. Please refer to the +# applicable agreement for further details. +# +# -------------------------------------------------------------------------- # +# +# Quartus II +# Version 9.1 Build 222 10/21/2009 SJ Full Version +# Date created = 10:23:26 March 26, 2010 +# +# -------------------------------------------------------------------------- # + +QUARTUS_VERSION = "9.1" +DATE = "10:23:26 March 26, 2010" + +# Revisions + +PROJECT_REVISION = "mjl_stratix" diff --git a/debouncing/mjl_stratix/mjl_stratix.qsf b/debouncing/mjl_stratix/mjl_stratix.qsf new file mode 100644 index 0000000..38f4fd0 --- /dev/null +++ b/debouncing/mjl_stratix/mjl_stratix.qsf @@ -0,0 +1,92 @@ +# -------------------------------------------------------------------------- # +# +# Copyright (C) 1991-2009 Altera Corporation +# Your use of Altera Corporation's design tools, logic functions +# and other software and tools, and its AMPP partner logic +# functions, and any output files from any of the foregoing +# (including device programming or simulation files), and any +# associated documentation or information are expressly subject +# to the terms and conditions of the Altera Program License +# Subscription Agreement, Altera MegaCore Function License +# Agreement, or other applicable license agreement, including, +# without limitation, that your use is for the sole purpose of +# programming logic devices manufactured by Altera and sold by +# Altera or its authorized distributors. Please refer to the +# applicable agreement for further details. +# +# -------------------------------------------------------------------------- # +# +# Quartus II +# Version 9.1 Build 222 10/21/2009 SJ Full Version +# Date created = 10:23:26 March 26, 2010 +# +# -------------------------------------------------------------------------- # +# +# Notes: +# +# 1) The default values for assignments are stored in the file: +# mjl_stratix_assignment_defaults.qdf +# If this file doesn't exist, see file: +# assignment_defaults.qdf +# +# 2) Altera recommends that you do not modify this file. This +# file is updated automatically by the Quartus II software +# and any changes you make may be lost or overwritten. +# +# -------------------------------------------------------------------------- # + + +set_global_assignment -name FAMILY Stratix +set_global_assignment -name DEVICE EP1S25F672C6 +set_global_assignment -name TOP_LEVEL_ENTITY debounce_top +set_global_assignment -name ORIGINAL_QUARTUS_VERSION 9.1 +set_global_assignment -name PROJECT_CREATION_TIME_DATE "10:23:26 MARCH 26, 2010" +set_global_assignment -name LAST_QUARTUS_VERSION 9.1 +set_global_assignment -name EDA_SIMULATION_TOOL "ModelSim (VHDL)" +set_global_assignment -name EDA_OUTPUT_DATA_FORMAT VHDL -section_id eda_simulation +set_global_assignment -name USE_GENERATED_PHYSICAL_CONSTRAINTS OFF -section_id eda_blast_fpga +set_global_assignment -name MISC_FILE mjl_stratix.dpf +set_global_assignment -name STRATIX_DEVICE_IO_STANDARD "3.3-V LVTTL" +set_global_assignment -name RESERVE_ALL_UNUSED_PINS "AS INPUT TRI-STATED WITH WEAK PULL-UP" +set_global_assignment -name RESERVE_ASDO_AFTER_CONFIGURATION "AS INPUT TRI-STATED" +set_global_assignment -name VHDL_FILE ../src/counter.vhd +set_global_assignment -name VHDL_FILE ../src/counter_beh.vhd +set_global_assignment -name VHDL_FILE ../src/debounce.vhd +set_global_assignment -name VHDL_FILE ../src/debounce_fsm.vhd +set_global_assignment -name VHDL_FILE ../src/debounce_fsm_beh.vhd +set_global_assignment -name VHDL_FILE ../src/debounce_pkg.vhd +set_global_assignment -name VHDL_FILE ../src/debounce_struct.vhd +set_global_assignment -name VHDL_FILE ../src/debounce_tb.vhd +set_global_assignment -name VHDL_FILE ../src/debounce_top.vhd +set_global_assignment -name VHDL_FILE ../src/debounce_top_struct.vhd +set_global_assignment -name VHDL_FILE ../src/event_counter.vhd +set_global_assignment -name VHDL_FILE ../src/event_counter_beh.vhd +set_global_assignment -name VHDL_FILE ../src/event_counter_pkg.vhd +set_global_assignment -name VHDL_FILE ../src/math_pkg.vhd +set_global_assignment -name VHDL_FILE ../src/sync.vhd +set_global_assignment -name VHDL_FILE ../src/sync_beh.vhd +set_global_assignment -name VHDL_FILE ../src/sync_pkg.vhd +set_location_assignment PIN_T2 -to seg_b[6] +set_location_assignment PIN_AA11 -to seg_b[5] +set_location_assignment PIN_R6 -to seg_b[4] +set_location_assignment PIN_R4 -to seg_b[3] +set_location_assignment PIN_N8 -to seg_b[2] +set_location_assignment PIN_Y11 -to seg_b[0] +set_location_assignment PIN_N7 -to seg_b[1] +set_location_assignment PIN_R23 -to seg_a[6] +set_location_assignment PIN_R22 -to seg_a[5] +set_location_assignment PIN_R21 -to seg_a[4] +set_location_assignment PIN_R20 -to seg_a[3] +set_location_assignment PIN_R19 -to seg_a[2] +set_location_assignment PIN_R9 -to seg_a[1] +set_location_assignment PIN_R8 -to seg_a[0] +set_location_assignment PIN_N3 -to sys_clk +set_location_assignment PIN_AF17 -to sys_res_n +set_location_assignment PIN_A3 -to btn_a +set_global_assignment -name FMAX_REQUIREMENT "33.33 MHz" -section_id sys_clk +set_instance_assignment -name CLOCK_SETTINGS sys_clk -to sys_clk +set_global_assignment -name LL_ROOT_REGION ON -section_id "Root Region" +set_global_assignment -name LL_MEMBER_STATE LOCKED -section_id "Root Region" +set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top +set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top +set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/debouncing/prj/create_project.cmd b/debouncing/prj/create_project.cmd new file mode 100644 index 0000000..ad98f04 --- /dev/null +++ b/debouncing/prj/create_project.cmd @@ -0,0 +1,4 @@ +cd .. +md mjl_stratix +cd mjl_stratix +quartus_sh -t ..\prj\create_project.tcl diff --git a/debouncing/prj/create_project.tcl b/debouncing/prj/create_project.tcl new file mode 100644 index 0000000..6d485a2 --- /dev/null +++ b/debouncing/prj/create_project.tcl @@ -0,0 +1,87 @@ +package require ::quartus::project + +set need_to_close_project 0 +set make_assignments 1 + +# Check that the right project is open +if {[is_project_open]} { + if {[string compare $quartus(project) "mjl_stratix"]} { + puts "Project mjl_stratix is not open" + set make_assignments 0 + } +} else { + # Only open if not already open + if {[project_exists mjl_stratix]} { + project_open -revision mjl_stratix mjl_stratix + } else { + project_new -revision mjl_stratix mjl_stratix + } + set need_to_close_project 1 +} + +# Make assignments +if {$make_assignments} { + set_global_assignment -name FAMILY Stratix + set_global_assignment -name DEVICE EP1S25F672C6 + set_global_assignment -name EDA_SIMULATION_TOOL "ModelSim (VHDL)" + set_global_assignment -name EDA_OUTPUT_DATA_FORMAT VHDL -section_id eda_simulation + set_global_assignment -name USE_GENERATED_PHYSICAL_CONSTRAINTS OFF -section_id eda_blast_fpga + set_global_assignment -name MISC_FILE "mjl_stratix.dpf" + set_global_assignment -name STRATIX_DEVICE_IO_STANDARD "3.3-V LVTTL" + set_global_assignment -name RESERVE_ALL_UNUSED_PINS "AS INPUT TRI-STATED WITH WEAK PULL-UP" + set_global_assignment -name RESERVE_ASDO_AFTER_CONFIGURATION "AS INPUT TRI-STATED" + + set_global_assignment -name TOP_LEVEL_ENTITY debounce_top + set_global_assignment -name VHDL_FILE ../src/counter.vhd + set_global_assignment -name VHDL_FILE ../src/counter_beh.vhd + set_global_assignment -name VHDL_FILE ../src/debounce.vhd + set_global_assignment -name VHDL_FILE ../src/debounce_fsm.vhd + set_global_assignment -name VHDL_FILE ../src/debounce_fsm_beh.vhd + set_global_assignment -name VHDL_FILE ../src/debounce_pkg.vhd + set_global_assignment -name VHDL_FILE ../src/debounce_struct.vhd + set_global_assignment -name VHDL_FILE ../src/debounce_tb.vhd + set_global_assignment -name VHDL_FILE ../src/debounce_top.vhd + set_global_assignment -name VHDL_FILE ../src/debounce_top_struct.vhd + set_global_assignment -name VHDL_FILE ../src/event_counter.vhd + set_global_assignment -name VHDL_FILE ../src/event_counter_beh.vhd + set_global_assignment -name VHDL_FILE ../src/event_counter_pkg.vhd + set_global_assignment -name VHDL_FILE ../src/math_pkg.vhd + set_global_assignment -name VHDL_FILE ../src/sync.vhd + set_global_assignment -name VHDL_FILE ../src/sync_beh.vhd + set_global_assignment -name VHDL_FILE ../src/sync_pkg.vhd + + set_location_assignment PIN_T2 -to seg_b[6] + set_location_assignment PIN_AA11 -to seg_b[5] + set_location_assignment PIN_R6 -to seg_b[4] + set_location_assignment PIN_R4 -to seg_b[3] + set_location_assignment PIN_N8 -to seg_b[2] + set_location_assignment PIN_Y11 -to seg_b[0] + set_location_assignment PIN_N7 -to seg_b[1] + set_location_assignment PIN_R23 -to seg_a[6] + set_location_assignment PIN_R22 -to seg_a[5] + set_location_assignment PIN_R21 -to seg_a[4] + set_location_assignment PIN_R20 -to seg_a[3] + set_location_assignment PIN_R19 -to seg_a[2] + set_location_assignment PIN_R9 -to seg_a[1] + set_location_assignment PIN_R8 -to seg_a[0] + set_location_assignment PIN_N3 -to sys_clk + set_location_assignment PIN_AF17 -to sys_res_n + set_location_assignment PIN_A3 -to btn_a + + set_global_assignment -name FMAX_REQUIREMENT "33.33 MHz" -section_id sys_clk + set_instance_assignment -name CLOCK_SETTINGS sys_clk -to sys_clk + + set_global_assignment -name LL_ROOT_REGION ON -section_id "Root Region" + set_global_assignment -name LL_MEMBER_STATE LOCKED -section_id "Root Region" + set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top + set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top + set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top + + # Commit assignments + export_assignments + + # Close project + if {$need_to_close_project} { + project_close + } +} diff --git a/debouncing/src/counter.vhd b/debouncing/src/counter.vhd new file mode 100644 index 0000000..1aac4c3 --- /dev/null +++ b/debouncing/src/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/debouncing/src/counter_beh.vhd b/debouncing/src/counter_beh.vhd new file mode 100644 index 0000000..75b711c --- /dev/null +++ b/debouncing/src/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/debouncing/src/debounce.vhd b/debouncing/src/debounce.vhd new file mode 100644 index 0000000..79a8d26 --- /dev/null +++ b/debouncing/src/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/debouncing/src/debounce_fsm.vhd b/debouncing/src/debounce_fsm.vhd new file mode 100644 index 0000000..dbc22b9 --- /dev/null +++ b/debouncing/src/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/debouncing/src/debounce_fsm_beh.vhd b/debouncing/src/debounce_fsm_beh.vhd new file mode 100644 index 0000000..f30d43b --- /dev/null +++ b/debouncing/src/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/debouncing/src/debounce_pkg.vhd b/debouncing/src/debounce_pkg.vhd new file mode 100644 index 0000000..08f5153 --- /dev/null +++ b/debouncing/src/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; \ No newline at end of file diff --git a/debouncing/src/debounce_struct.vhd b/debouncing/src/debounce_struct.vhd new file mode 100644 index 0000000..5e3684c --- /dev/null +++ b/debouncing/src/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/debouncing/src/debounce_tb.vhd b/debouncing/src/debounce_tb.vhd new file mode 100644 index 0000000..ce4744c --- /dev/null +++ b/debouncing/src/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/debouncing/src/debounce_top.vhd b/debouncing/src/debounce_top.vhd new file mode 100644 index 0000000..0152c5c --- /dev/null +++ b/debouncing/src/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/debouncing/src/debounce_top_struct.vhd b/debouncing/src/debounce_top_struct.vhd new file mode 100644 index 0000000..3d1bcb8 --- /dev/null +++ b/debouncing/src/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/debouncing/src/event_counter.vhd b/debouncing/src/event_counter.vhd new file mode 100644 index 0000000..9d5aadc --- /dev/null +++ b/debouncing/src/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/debouncing/src/event_counter_beh.vhd b/debouncing/src/event_counter_beh.vhd new file mode 100644 index 0000000..9d7b8b8 --- /dev/null +++ b/debouncing/src/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/debouncing/src/event_counter_pkg.vhd b/debouncing/src/event_counter_pkg.vhd new file mode 100644 index 0000000..bf0c2f7 --- /dev/null +++ b/debouncing/src/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; \ No newline at end of file diff --git a/debouncing/src/math_pkg.vhd b/debouncing/src/math_pkg.vhd new file mode 100644 index 0000000..6205e47 --- /dev/null +++ b/debouncing/src/math_pkg.vhd @@ -0,0 +1,53 @@ +------------------------------------------------------------------------- +-- +-- Filename: math_pkg.vhd +-- ========= +-- +-- Short Description: +-- ================== +-- Utility Package defining often used mathematical functions +-- +------------------------------------------------------------------------- + +package math_pkg is + -- Calculates the logarithm dualis of the operand and rounds up + -- the result to the next integer value. + function log2c(constant value : in integer) return integer; + -- Returns the maximum of the two operands + function max(constant value1, value2 : in integer) return integer; + -- Returns the maximum of the three operands + function max(constant value1, value2, value3 : in integer) return integer; +end math_pkg; + +package body math_pkg is + function log2c(constant value : in integer) return integer is + variable ret_value : integer; + variable cur_value : integer; + begin + ret_value := 0; + cur_value := 1; + + while cur_value < value loop + ret_value := ret_value + 1; + cur_value := cur_value * 2; + end loop; + return ret_value; + end function log2c; + + function max(constant value1, value2 : in integer) return integer is + variable ret_value : integer; + begin + if value1 > value2 then + ret_value := value1; + else + ret_value := value2; + end if; + return ret_value; + end function max; + + function max(constant value1, value2, value3 : in integer) return integer is + begin + return max(max(value1, value2), value3); + end function max; + end package body math_pkg; + \ No newline at end of file diff --git a/debouncing/src/sync.vhd b/debouncing/src/sync.vhd new file mode 100644 index 0000000..8515bd6 --- /dev/null +++ b/debouncing/src/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/debouncing/src/sync_beh.vhd b/debouncing/src/sync_beh.vhd new file mode 100644 index 0000000..826bb12 --- /dev/null +++ b/debouncing/src/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/debouncing/src/sync_pkg.vhd b/debouncing/src/sync_pkg.vhd new file mode 100644 index 0000000..2b6247f --- /dev/null +++ b/debouncing/src/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; \ No newline at end of file -- 2.25.1