debouncing example
authorBernhard Urban <lewurm@gmail.com>
Fri, 26 Mar 2010 19:00:20 +0000 (20:00 +0100)
committerBernhard Urban <lewurm@gmail.com>
Fri, 26 Mar 2010 19:00:20 +0000 (20:00 +0100)
22 files changed:
debouncing/mjl_stratix/db/mjl_stratix.db_info [new file with mode: 0644]
debouncing/mjl_stratix/mjl_stratix.qpf [new file with mode: 0644]
debouncing/mjl_stratix/mjl_stratix.qsf [new file with mode: 0644]
debouncing/prj/create_project.cmd [new file with mode: 0644]
debouncing/prj/create_project.tcl [new file with mode: 0644]
debouncing/src/counter.vhd [new file with mode: 0644]
debouncing/src/counter_beh.vhd [new file with mode: 0644]
debouncing/src/debounce.vhd [new file with mode: 0644]
debouncing/src/debounce_fsm.vhd [new file with mode: 0644]
debouncing/src/debounce_fsm_beh.vhd [new file with mode: 0644]
debouncing/src/debounce_pkg.vhd [new file with mode: 0644]
debouncing/src/debounce_struct.vhd [new file with mode: 0644]
debouncing/src/debounce_tb.vhd [new file with mode: 0644]
debouncing/src/debounce_top.vhd [new file with mode: 0644]
debouncing/src/debounce_top_struct.vhd [new file with mode: 0644]
debouncing/src/event_counter.vhd [new file with mode: 0644]
debouncing/src/event_counter_beh.vhd [new file with mode: 0644]
debouncing/src/event_counter_pkg.vhd [new file with mode: 0644]
debouncing/src/math_pkg.vhd [new file with mode: 0644]
debouncing/src/sync.vhd [new file with mode: 0644]
debouncing/src/sync_beh.vhd [new file with mode: 0644]
debouncing/src/sync_pkg.vhd [new file with mode: 0644]

diff --git a/debouncing/mjl_stratix/db/mjl_stratix.db_info b/debouncing/mjl_stratix/db/mjl_stratix.db_info
new file mode 100644 (file)
index 0000000..9eab77b
--- /dev/null
@@ -0,0 +1,3 @@
+Quartus_Version = Version 9.1 Build 222 10/21/2009 SJ Full Version\r
+Version_Index = 184606208\r
+Creation_Time = Fri Mar 26 10:23:27 2010\r
diff --git a/debouncing/mjl_stratix/mjl_stratix.qpf b/debouncing/mjl_stratix/mjl_stratix.qpf
new file mode 100644 (file)
index 0000000..4721af9
--- /dev/null
@@ -0,0 +1,30 @@
+# -------------------------------------------------------------------------- #\r
+#\r
+# Copyright (C) 1991-2009 Altera Corporation\r
+# Your use of Altera Corporation's design tools, logic functions \r
+# and other software and tools, and its AMPP partner logic \r
+# functions, and any output files from any of the foregoing \r
+# (including device programming or simulation files), and any \r
+# associated documentation or information are expressly subject \r
+# to the terms and conditions of the Altera Program License \r
+# Subscription Agreement, Altera MegaCore Function License \r
+# Agreement, or other applicable license agreement, including, \r
+# without limitation, that your use is for the sole purpose of \r
+# programming logic devices manufactured by Altera and sold by \r
+# Altera or its authorized distributors.  Please refer to the \r
+# applicable agreement for further details.\r
+#\r
+# -------------------------------------------------------------------------- #\r
+#\r
+# Quartus II\r
+# Version 9.1 Build 222 10/21/2009 SJ Full Version\r
+# Date created = 10:23:26  March 26, 2010\r
+#\r
+# -------------------------------------------------------------------------- #\r
+\r
+QUARTUS_VERSION = "9.1"\r
+DATE = "10:23:26  March 26, 2010"\r
+\r
+# Revisions\r
+\r
+PROJECT_REVISION = "mjl_stratix"\r
diff --git a/debouncing/mjl_stratix/mjl_stratix.qsf b/debouncing/mjl_stratix/mjl_stratix.qsf
new file mode 100644 (file)
index 0000000..38f4fd0
--- /dev/null
@@ -0,0 +1,92 @@
+# -------------------------------------------------------------------------- #\r
+#\r
+# Copyright (C) 1991-2009 Altera Corporation\r
+# Your use of Altera Corporation's design tools, logic functions \r
+# and other software and tools, and its AMPP partner logic \r
+# functions, and any output files from any of the foregoing \r
+# (including device programming or simulation files), and any \r
+# associated documentation or information are expressly subject \r
+# to the terms and conditions of the Altera Program License \r
+# Subscription Agreement, Altera MegaCore Function License \r
+# Agreement, or other applicable license agreement, including, \r
+# without limitation, that your use is for the sole purpose of \r
+# programming logic devices manufactured by Altera and sold by \r
+# Altera or its authorized distributors.  Please refer to the \r
+# applicable agreement for further details.\r
+#\r
+# -------------------------------------------------------------------------- #\r
+#\r
+# Quartus II\r
+# Version 9.1 Build 222 10/21/2009 SJ Full Version\r
+# Date created = 10:23:26  March 26, 2010\r
+#\r
+# -------------------------------------------------------------------------- #\r
+#\r
+# Notes:\r
+#\r
+# 1) The default values for assignments are stored in the file:\r
+#              mjl_stratix_assignment_defaults.qdf\r
+#    If this file doesn't exist, see file:\r
+#              assignment_defaults.qdf\r
+#\r
+# 2) Altera recommends that you do not modify this file. This\r
+#    file is updated automatically by the Quartus II software\r
+#    and any changes you make may be lost or overwritten.\r
+#\r
+# -------------------------------------------------------------------------- #\r
+\r
+\r
+set_global_assignment -name FAMILY Stratix\r
+set_global_assignment -name DEVICE EP1S25F672C6\r
+set_global_assignment -name TOP_LEVEL_ENTITY debounce_top\r
+set_global_assignment -name ORIGINAL_QUARTUS_VERSION 9.1\r
+set_global_assignment -name PROJECT_CREATION_TIME_DATE "10:23:26  MARCH 26, 2010"\r
+set_global_assignment -name LAST_QUARTUS_VERSION 9.1\r
+set_global_assignment -name EDA_SIMULATION_TOOL "ModelSim (VHDL)"\r
+set_global_assignment -name EDA_OUTPUT_DATA_FORMAT VHDL -section_id eda_simulation\r
+set_global_assignment -name USE_GENERATED_PHYSICAL_CONSTRAINTS OFF -section_id eda_blast_fpga\r
+set_global_assignment -name MISC_FILE mjl_stratix.dpf\r
+set_global_assignment -name STRATIX_DEVICE_IO_STANDARD "3.3-V LVTTL"\r
+set_global_assignment -name RESERVE_ALL_UNUSED_PINS "AS INPUT TRI-STATED WITH WEAK PULL-UP"\r
+set_global_assignment -name RESERVE_ASDO_AFTER_CONFIGURATION "AS INPUT TRI-STATED"\r
+set_global_assignment -name VHDL_FILE ../src/counter.vhd\r
+set_global_assignment -name VHDL_FILE ../src/counter_beh.vhd\r
+set_global_assignment -name VHDL_FILE ../src/debounce.vhd\r
+set_global_assignment -name VHDL_FILE ../src/debounce_fsm.vhd\r
+set_global_assignment -name VHDL_FILE ../src/debounce_fsm_beh.vhd\r
+set_global_assignment -name VHDL_FILE ../src/debounce_pkg.vhd\r
+set_global_assignment -name VHDL_FILE ../src/debounce_struct.vhd\r
+set_global_assignment -name VHDL_FILE ../src/debounce_tb.vhd\r
+set_global_assignment -name VHDL_FILE ../src/debounce_top.vhd\r
+set_global_assignment -name VHDL_FILE ../src/debounce_top_struct.vhd\r
+set_global_assignment -name VHDL_FILE ../src/event_counter.vhd\r
+set_global_assignment -name VHDL_FILE ../src/event_counter_beh.vhd\r
+set_global_assignment -name VHDL_FILE ../src/event_counter_pkg.vhd\r
+set_global_assignment -name VHDL_FILE ../src/math_pkg.vhd\r
+set_global_assignment -name VHDL_FILE ../src/sync.vhd\r
+set_global_assignment -name VHDL_FILE ../src/sync_beh.vhd\r
+set_global_assignment -name VHDL_FILE ../src/sync_pkg.vhd\r
+set_location_assignment PIN_T2 -to seg_b[6]\r
+set_location_assignment PIN_AA11 -to seg_b[5]\r
+set_location_assignment PIN_R6 -to seg_b[4]\r
+set_location_assignment PIN_R4 -to seg_b[3]\r
+set_location_assignment PIN_N8 -to seg_b[2]\r
+set_location_assignment PIN_Y11 -to seg_b[0]\r
+set_location_assignment PIN_N7 -to seg_b[1]\r
+set_location_assignment PIN_R23 -to seg_a[6]\r
+set_location_assignment PIN_R22 -to seg_a[5]\r
+set_location_assignment PIN_R21 -to seg_a[4]\r
+set_location_assignment PIN_R20 -to seg_a[3]\r
+set_location_assignment PIN_R19 -to seg_a[2]\r
+set_location_assignment PIN_R9 -to seg_a[1]\r
+set_location_assignment PIN_R8 -to seg_a[0]\r
+set_location_assignment PIN_N3 -to sys_clk\r
+set_location_assignment PIN_AF17 -to sys_res_n\r
+set_location_assignment PIN_A3 -to btn_a\r
+set_global_assignment -name FMAX_REQUIREMENT "33.33 MHz" -section_id sys_clk\r
+set_instance_assignment -name CLOCK_SETTINGS sys_clk -to sys_clk\r
+set_global_assignment -name LL_ROOT_REGION ON -section_id "Root Region"\r
+set_global_assignment -name LL_MEMBER_STATE LOCKED -section_id "Root Region"\r
+set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top\r
+set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top\r
+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 (file)
index 0000000..ad98f04
--- /dev/null
@@ -0,0 +1,4 @@
+cd ..\r
+md mjl_stratix\r
+cd mjl_stratix\r
+quartus_sh -t ..\prj\create_project.tcl\r
diff --git a/debouncing/prj/create_project.tcl b/debouncing/prj/create_project.tcl
new file mode 100644 (file)
index 0000000..6d485a2
--- /dev/null
@@ -0,0 +1,87 @@
+package require ::quartus::project\r
+\r
+set need_to_close_project 0\r
+set make_assignments 1\r
+\r
+# Check that the right project is open\r
+if {[is_project_open]} {\r
+       if {[string compare $quartus(project) "mjl_stratix"]} {\r
+               puts "Project mjl_stratix is not open"\r
+               set make_assignments 0\r
+       }\r
+} else {\r
+       # Only open if not already open\r
+       if {[project_exists mjl_stratix]} {\r
+               project_open -revision mjl_stratix mjl_stratix\r
+       } else {\r
+               project_new -revision mjl_stratix mjl_stratix\r
+       }\r
+       set need_to_close_project 1\r
+}\r
+\r
+# Make assignments\r
+if {$make_assignments} {\r
+       set_global_assignment -name FAMILY Stratix\r
+       set_global_assignment -name DEVICE EP1S25F672C6\r
+       set_global_assignment -name EDA_SIMULATION_TOOL "ModelSim (VHDL)"\r
+       set_global_assignment -name EDA_OUTPUT_DATA_FORMAT VHDL -section_id eda_simulation\r
+       set_global_assignment -name USE_GENERATED_PHYSICAL_CONSTRAINTS OFF -section_id eda_blast_fpga\r
+       set_global_assignment -name MISC_FILE "mjl_stratix.dpf"\r
+       set_global_assignment -name STRATIX_DEVICE_IO_STANDARD "3.3-V LVTTL"\r
+       set_global_assignment -name RESERVE_ALL_UNUSED_PINS "AS INPUT TRI-STATED WITH WEAK PULL-UP"\r
+       set_global_assignment -name RESERVE_ASDO_AFTER_CONFIGURATION "AS INPUT TRI-STATED"\r
+\r
+       set_global_assignment -name TOP_LEVEL_ENTITY debounce_top\r
+       set_global_assignment -name VHDL_FILE ../src/counter.vhd\r
+       set_global_assignment -name VHDL_FILE ../src/counter_beh.vhd\r
+       set_global_assignment -name VHDL_FILE ../src/debounce.vhd\r
+       set_global_assignment -name VHDL_FILE ../src/debounce_fsm.vhd\r
+       set_global_assignment -name VHDL_FILE ../src/debounce_fsm_beh.vhd\r
+       set_global_assignment -name VHDL_FILE ../src/debounce_pkg.vhd\r
+       set_global_assignment -name VHDL_FILE ../src/debounce_struct.vhd\r
+       set_global_assignment -name VHDL_FILE ../src/debounce_tb.vhd\r
+       set_global_assignment -name VHDL_FILE ../src/debounce_top.vhd\r
+       set_global_assignment -name VHDL_FILE ../src/debounce_top_struct.vhd\r
+       set_global_assignment -name VHDL_FILE ../src/event_counter.vhd\r
+       set_global_assignment -name VHDL_FILE ../src/event_counter_beh.vhd\r
+       set_global_assignment -name VHDL_FILE ../src/event_counter_pkg.vhd\r
+       set_global_assignment -name VHDL_FILE ../src/math_pkg.vhd\r
+       set_global_assignment -name VHDL_FILE ../src/sync.vhd\r
+       set_global_assignment -name VHDL_FILE ../src/sync_beh.vhd\r
+       set_global_assignment -name VHDL_FILE ../src/sync_pkg.vhd\r
+\r
+       set_location_assignment PIN_T2 -to seg_b[6]\r
+       set_location_assignment PIN_AA11 -to seg_b[5]\r
+       set_location_assignment PIN_R6 -to seg_b[4]\r
+       set_location_assignment PIN_R4 -to seg_b[3]\r
+       set_location_assignment PIN_N8 -to seg_b[2]\r
+       set_location_assignment PIN_Y11 -to seg_b[0]\r
+       set_location_assignment PIN_N7 -to seg_b[1]\r
+       set_location_assignment PIN_R23 -to seg_a[6]\r
+       set_location_assignment PIN_R22 -to seg_a[5]\r
+       set_location_assignment PIN_R21 -to seg_a[4]\r
+       set_location_assignment PIN_R20 -to seg_a[3]\r
+       set_location_assignment PIN_R19 -to seg_a[2]\r
+       set_location_assignment PIN_R9 -to seg_a[1]\r
+       set_location_assignment PIN_R8 -to seg_a[0]\r
+       set_location_assignment PIN_N3 -to sys_clk\r
+       set_location_assignment PIN_AF17 -to sys_res_n\r
+     set_location_assignment PIN_A3 -to btn_a\r
+\r
+       set_global_assignment -name FMAX_REQUIREMENT "33.33 MHz" -section_id sys_clk\r
+       set_instance_assignment -name CLOCK_SETTINGS sys_clk -to sys_clk\r
+\r
+       set_global_assignment -name LL_ROOT_REGION ON -section_id "Root Region"\r
+       set_global_assignment -name LL_MEMBER_STATE LOCKED -section_id "Root Region"\r
+       set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top\r
+       set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top\r
+       set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top\r
+\r
+       # Commit assignments\r
+       export_assignments\r
+\r
+       # Close project\r
+       if {$need_to_close_project} {\r
+               project_close\r
+       }\r
+}\r
diff --git a/debouncing/src/counter.vhd b/debouncing/src/counter.vhd
new file mode 100644 (file)
index 0000000..1aac4c3
--- /dev/null
@@ -0,0 +1,17 @@
+library ieee;\r
+use ieee.std_logic_1164.all;\r
+use work.math_pkg.all;\r
+\r
+entity counter is\r
+  generic\r
+  (\r
+    CNT_MAX : integer range 2 to integer'high\r
+  );\r
+  port\r
+  (\r
+    sys_clk : in std_logic;\r
+    sys_res_n : in std_logic;\r
+    clear_cnt : in std_logic;\r
+    cnt : out std_logic_vector(log2c(CNT_MAX) - 1 downto 0)\r
+  );\r
+end entity counter;\r
diff --git a/debouncing/src/counter_beh.vhd b/debouncing/src/counter_beh.vhd
new file mode 100644 (file)
index 0000000..75b711c
--- /dev/null
@@ -0,0 +1,30 @@
+library ieee;\r
+use ieee.std_logic_1164.all;\r
+use ieee.numeric_std.all;\r
+use work.math_pkg.all;\r
+\r
+architecture beh of counter is\r
+  signal cnt_int, cnt_next : integer range 0 to CNT_MAX;\r
+begin\r
+  cnt <= std_logic_vector(to_unsigned(cnt_int, log2c(CNT_MAX)));\r
+\r
+  process(sys_clk, sys_res_n)\r
+  begin\r
+    if sys_res_n = '0' then\r
+      cnt_int <= 0;\r
+    elsif rising_edge(sys_clk) then\r
+      cnt_int <= cnt_next;\r
+    end if;\r
+  end process;\r
+\r
+  process(cnt_int, clear_cnt)\r
+  begin\r
+    cnt_next <= cnt_int;\r
+\r
+    if clear_cnt = '1' then\r
+      cnt_next <= 0;\r
+    elsif cnt_int < CNT_MAX then\r
+      cnt_next <= cnt_int + 1;\r
+    end if;\r
+  end process;\r
+end architecture beh;\r
diff --git a/debouncing/src/debounce.vhd b/debouncing/src/debounce.vhd
new file mode 100644 (file)
index 0000000..79a8d26
--- /dev/null
@@ -0,0 +1,20 @@
+library ieee;\r
+use ieee.std_logic_1164.all;\r
+\r
+entity debounce is\r
+  generic\r
+  (\r
+    CLK_FREQ    : integer;\r
+    TIMEOUT     : time range 100 us to 100 ms := 1 ms;\r
+    RESET_VALUE : std_logic := '0';\r
+    SYNC_STAGES : integer range 2 to integer'high\r
+  );\r
+  port\r
+  (\r
+    sys_clk : in std_logic;\r
+    sys_res_n : in std_logic;\r
+\r
+    data_in : in std_logic;\r
+    data_out : out std_logic\r
+  );\r
+end entity debounce;\r
diff --git a/debouncing/src/debounce_fsm.vhd b/debouncing/src/debounce_fsm.vhd
new file mode 100644 (file)
index 0000000..dbc22b9
--- /dev/null
@@ -0,0 +1,20 @@
+library ieee;\r
+use ieee.std_logic_1164.all;\r
+use work.math_pkg.all;\r
+\r
+entity debounce_fsm is\r
+  generic\r
+  (\r
+    RESET_VALUE : std_logic;\r
+    CNT_MAX : integer range 2 to integer'high\r
+  );\r
+  port\r
+  (\r
+    sys_clk : in std_logic;\r
+    sys_res_n : in std_logic;\r
+    i : in std_logic;\r
+    cnt : in std_logic_vector(log2c(CNT_MAX) - 1 downto 0);\r
+    clear_cnt : out std_logic;\r
+    o : out std_logic\r
+  );\r
+end entity debounce_fsm;\r
diff --git a/debouncing/src/debounce_fsm_beh.vhd b/debouncing/src/debounce_fsm_beh.vhd
new file mode 100644 (file)
index 0000000..f30d43b
--- /dev/null
@@ -0,0 +1,71 @@
+library ieee;\r
+use ieee.std_logic_1164.all;\r
+use ieee.numeric_std.all;\r
+\r
+architecture beh of debounce_fsm is\r
+  type DEBOUNCE_FSM_STATE_TYPE is\r
+    (IDLE0, TIMEOUT0, IDLE1, TIMEOUT1);\r
+  signal debounce_fsm_state, debounce_fsm_state_next : DEBOUNCE_FSM_STATE_TYPE;\r
+begin\r
+  next_state : process(debounce_fsm_state, i, cnt)\r
+  begin\r
+    debounce_fsm_state_next <= debounce_fsm_state;\r
+    case debounce_fsm_state is\r
+      when IDLE0 =>\r
+        if i = '1' then\r
+          debounce_fsm_state_next <= TIMEOUT0;\r
+        end if;\r
+      when TIMEOUT0 =>\r
+        if i = '0' then\r
+          debounce_fsm_state_next <= IDLE0;\r
+        elsif to_integer(unsigned(cnt)) = CNT_MAX then\r
+          debounce_fsm_state_next <= IDLE1;\r
+        end if;\r
+      when IDLE1 =>\r
+        if i = '0' then\r
+          debounce_fsm_state_next <= TIMEOUT1;\r
+        end if;\r
+      when TIMEOUT1 =>\r
+        if i = '1' then\r
+          debounce_fsm_state_next <= IDLE1;\r
+        elsif to_integer(unsigned(cnt)) = CNT_MAX then\r
+          debounce_fsm_state_next <= IDLE0;\r
+        end if;\r
+    end case;\r
+  end process next_state;\r
+\r
+  output : process(debounce_fsm_state)\r
+  begin\r
+    o <= RESET_VALUE;\r
+    clear_cnt <= '1';\r
+\r
+    case debounce_fsm_state is\r
+      when IDLE0 =>\r
+        o <= '0';\r
+      when TIMEOUT0 =>\r
+        o <= '0';\r
+        clear_cnt <= '0';\r
+      when IDLE1 =>\r
+        o <= '1';\r
+      when TIMEOUT1 =>\r
+        o <= '1';\r
+        clear_cnt <= '0';\r
+    end case;\r
+  end process output;\r
+\r
+  assert RESET_VALUE = '0' or RESET_VALUE = '1' report\r
+    "RESET_VALUE may only be 0 or 1!" severity failure;\r
+\r
+  sync : process(sys_clk, sys_res_n)\r
+  begin\r
+    if sys_res_n = '0' then\r
+      if RESET_VALUE = '0' then\r
+        debounce_fsm_state <= IDLE0;\r
+      else\r
+        debounce_fsm_state <= IDLE1;\r
+      end if;\r
+    elsif rising_edge(sys_clk) then\r
+      debounce_fsm_state <= debounce_fsm_state_next;\r
+    end if;\r
+  end process sync;\r
+end architecture beh;\r
diff --git a/debouncing/src/debounce_pkg.vhd b/debouncing/src/debounce_pkg.vhd
new file mode 100644 (file)
index 0000000..08f5153
--- /dev/null
@@ -0,0 +1,54 @@
+library ieee;\r
+use ieee.std_logic_1164.all;\r
+use work.math_pkg.all;\r
+\r
+package debounce_pkg is\r
+  component debounce_fsm is\r
+    generic\r
+    (\r
+      RESET_VALUE : std_logic;\r
+      CNT_MAX : integer range 2 to integer'high\r
+    );\r
+    port\r
+    (\r
+      sys_clk : in std_logic;\r
+      sys_res_n : in std_logic;\r
+      i : in std_logic;\r
+      cnt : in std_logic_vector(log2c(CNT_MAX) - 1 downto 0);\r
+      clear_cnt : out std_logic;\r
+      o : out std_logic\r
+    );\r
+  end component debounce_fsm;\r
+\r
+  component counter is\r
+    generic\r
+    (\r
+      CNT_MAX : integer range 2 to integer'high\r
+    );\r
+    port\r
+    (\r
+      sys_clk : in std_logic;\r
+      sys_res_n : in std_logic;\r
+      clear_cnt : in std_logic;\r
+      cnt : out std_logic_vector(log2c(CNT_MAX) - 1 downto 0)\r
+    );\r
+  end component counter;\r
+\r
+  component debounce is\r
+    generic\r
+    (\r
+      CLK_FREQ    : integer;\r
+      TIMEOUT     : time range 100 us to 100 ms := 1 ms;\r
+      RESET_VALUE : std_logic := '0';\r
+      SYNC_STAGES : integer range 2 to integer'high\r
+    );\r
+    port\r
+    (\r
+      sys_clk : in std_logic;\r
+      sys_res_n : in std_logic;\r
+\r
+      data_in : in std_logic;\r
+      data_out : out std_logic\r
+    );\r
+  end component debounce;\r
+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 (file)
index 0000000..5e3684c
--- /dev/null
@@ -0,0 +1,56 @@
+library ieee;\r
+use ieee.std_logic_1164.all;\r
+use work.sync_pkg.all;\r
+use work.debounce_pkg.all;\r
+use work.math_pkg.all;\r
+\r
+architecture struct of debounce is\r
+  constant CLK_PERIOD : time := 1E9 / CLK_FREQ * 1 ns;\r
+  constant CNT_MAX : integer := TIMEOUT / CLK_PERIOD;\r
+  signal data_sync : std_logic;\r
+  signal clear_cnt : std_logic;\r
+  signal cnt : std_logic_vector(log2c(CNT_MAX) - 1 downto 0);\r
+begin\r
+  sync_inst : sync\r
+    generic map\r
+    (\r
+      SYNC_STAGES => SYNC_STAGES,\r
+      RESET_VALUE => RESET_VALUE\r
+    )\r
+    port map\r
+    (\r
+      sys_clk => sys_clk,\r
+      sys_res_n => sys_res_n,\r
+      data_in => data_in,\r
+      data_out => data_sync\r
+    );\r
+\r
+  fsm_inst : debounce_fsm\r
+    generic map\r
+    (\r
+      RESET_VALUE => RESET_VALUE,\r
+      CNT_MAX => CNT_MAX\r
+    )\r
+    port map\r
+    (\r
+      sys_clk => sys_clk,\r
+      sys_res_n => sys_res_n,\r
+      i => data_sync,\r
+      o => data_out,\r
+      clear_cnt => clear_cnt,\r
+      cnt => cnt\r
+    );\r
+\r
+  counter_inst : counter\r
+    generic map\r
+    (\r
+      CNT_MAX => CNT_MAX\r
+    )\r
+    port map\r
+    (\r
+      sys_clk => sys_clk,\r
+      sys_res_n => sys_res_n,\r
+      clear_cnt => clear_cnt,\r
+      cnt => cnt\r
+    );\r
+end architecture struct;\r
diff --git a/debouncing/src/debounce_tb.vhd b/debouncing/src/debounce_tb.vhd
new file mode 100644 (file)
index 0000000..ce4744c
--- /dev/null
@@ -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 (file)
index 0000000..0152c5c
--- /dev/null
@@ -0,0 +1,13 @@
+library ieee;\r
+use ieee.std_logic_1164.all;\r
+\r
+entity debounce_top is\r
+  port\r
+  (\r
+    sys_clk : in std_logic;\r
+    sys_res_n : in std_logic;\r
+    btn_a : in std_logic;\r
+    seg_a : out std_logic_vector(6 downto 0);\r
+    seg_b : out std_logic_vector(6 downto 0)\r
+  );\r
+end entity debounce_top;\r
diff --git a/debouncing/src/debounce_top_struct.vhd b/debouncing/src/debounce_top_struct.vhd
new file mode 100644 (file)
index 0000000..3d1bcb8
--- /dev/null
@@ -0,0 +1,90 @@
+library ieee;\r
+use ieee.std_logic_1164.all;\r
+use work.debounce_pkg.all;\r
+use work.sync_pkg.all;\r
+use work.event_counter_pkg.all;\r
+\r
+architecture struct of debounce_top is\r
+  constant CLK_FREQ : integer := 33330000;\r
+  constant TIMEOUT : time := 1 ms;\r
+  constant RES_N_DEFAULT_VALUE : std_logic := '1';\r
+  constant SYNC_STAGES : integer := 2;\r
+  constant BTN_A_RESET_VALUE : std_logic := '1';\r
+  constant EVENT_CNT_WIDTH : integer := 8;\r
+\r
+  signal sys_res_n_sync, btn_a_sync : std_logic;\r
+  signal event_cnt : std_logic_vector(EVENT_CNT_WIDTH - 1 downto 0);\r
+\r
+  function to_segs(value : in std_logic_vector(3 downto 0)) return std_logic_vector is\r
+  begin\r
+    case value is\r
+      when x"0" => return "1000000";\r
+      when x"1" => return "1111001";\r
+      when x"2" => return "0100100";\r
+      when x"3" => return "0110000";\r
+      when x"4" => return "0011001";\r
+      when x"5" => return "0010010";\r
+      when x"6" => return "0000010";\r
+      when x"7" => return "1111000";\r
+      when x"8" => return "0000000";\r
+      when x"9" => return "0010000";\r
+      when x"A" => return "0001000";\r
+      when x"B" => return "0000011";\r
+      when x"C" => return "1000110";\r
+      when x"D" => return "0100001";\r
+      when x"E" => return "0000110";\r
+      when x"F" => return "0001110";\r
+      when others => return "1111111";\r
+    end case;\r
+  end function;  \r
+begin\r
+  sys_res_n_debounce_inst : debounce\r
+    generic map\r
+    (\r
+      CLK_FREQ => CLK_FREQ,\r
+      TIMEOUT => TIMEOUT,\r
+      RESET_VALUE => RES_N_DEFAULT_VALUE,\r
+      SYNC_STAGES => SYNC_STAGES\r
+    )\r
+    port map\r
+    (\r
+      sys_clk => sys_clk,\r
+      sys_res_n => '1',\r
+      data_in => sys_res_n,\r
+      data_out => sys_res_n_sync\r
+    );\r
+\r
+    btn_a_debounce_inst : debounce\r
+    generic map\r
+    (\r
+      CLK_FREQ => CLK_FREQ,\r
+      TIMEOUT => TIMEOUT,\r
+      RESET_VALUE => BTN_A_RESET_VALUE,\r
+      SYNC_STAGES => SYNC_STAGES\r
+    )\r
+    port map\r
+    (\r
+      sys_clk => sys_clk,\r
+      sys_res_n => sys_res_n_sync,\r
+      data_in => btn_a,\r
+      data_out => btn_a_sync\r
+    );\r
+\r
+  event_cnt_inst : event_counter\r
+    generic map\r
+    (\r
+      CNT_WIDTH => EVENT_CNT_WIDTH,\r
+      RESET_VALUE => BTN_A_RESET_VALUE\r
+    )\r
+    port map\r
+    (\r
+      sys_clk => sys_clk,\r
+      sys_res_n => sys_res_n_sync,\r
+      sense => btn_a_sync,\r
+      cnt => event_cnt\r
+    );\r
+\r
+  seg_a <= to_segs(event_cnt(3 downto 0));\r
+  seg_b <= to_segs(event_cnt(7 downto 4));\r
+\r
+end architecture struct;\r
diff --git a/debouncing/src/event_counter.vhd b/debouncing/src/event_counter.vhd
new file mode 100644 (file)
index 0000000..9d5aadc
--- /dev/null
@@ -0,0 +1,17 @@
+library ieee;\r
+use ieee.std_logic_1164.all;\r
+\r
+entity event_counter is\r
+  generic\r
+  (\r
+    CNT_WIDTH : integer range 4 to integer'high;\r
+    RESET_VALUE : std_logic\r
+  );\r
+  port\r
+  (\r
+    sys_clk : in std_logic;\r
+    sys_res_n : in std_logic;\r
+    sense : in std_logic;\r
+    cnt : out std_logic_vector(CNT_WIDTH - 1 downto 0)\r
+  );\r
+end entity event_counter;\r
diff --git a/debouncing/src/event_counter_beh.vhd b/debouncing/src/event_counter_beh.vhd
new file mode 100644 (file)
index 0000000..9d7b8b8
--- /dev/null
@@ -0,0 +1,31 @@
+library ieee;\r
+use ieee.std_logic_1164.all;\r
+use ieee.numeric_std.all;\r
+\r
+architecture beh of event_counter is\r
+  signal sense_old, sense_old_next : std_logic;\r
+  signal cnt_int, cnt_next : std_logic_vector(CNT_WIDTH - 1 downto 0);\r
+begin\r
+  cnt <= cnt_int;\r
+\r
+  process(sys_clk, sys_res_n)\r
+  begin\r
+    if sys_res_n = '0' then\r
+      cnt_int <= (others => '0');\r
+      sense_old <= RESET_VALUE;\r
+    elsif rising_edge(sys_clk) then\r
+      cnt_int <= cnt_next;\r
+      sense_old <= sense_old_next;\r
+    end if;\r
+  end process;\r
+  \r
+  process(cnt_int, sense, sense_old)\r
+  begin\r
+    sense_old_next <= sense;\r
+    cnt_next <= cnt_int;\r
+\r
+    if sense_old /= sense and sense = '0' then\r
+      cnt_next <= std_logic_vector(unsigned(cnt_int) + 1);\r
+    end if;\r
+  end process;\r
+end architecture beh;\r
diff --git a/debouncing/src/event_counter_pkg.vhd b/debouncing/src/event_counter_pkg.vhd
new file mode 100644 (file)
index 0000000..bf0c2f7
--- /dev/null
@@ -0,0 +1,19 @@
+library ieee;\r
+use ieee.std_logic_1164.all;\r
+\r
+package event_counter_pkg is\r
+  component event_counter is\r
+    generic\r
+    (\r
+      CNT_WIDTH : integer range 4 to integer'high;\r
+      RESET_VALUE : std_logic\r
+    );\r
+    port\r
+    (\r
+      sys_clk : in std_logic;\r
+      sys_res_n : in std_logic;\r
+      sense : in std_logic;\r
+      cnt : out std_logic_vector(CNT_WIDTH - 1 downto 0)\r
+    );\r
+  end component event_counter;\r
+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 (file)
index 0000000..6205e47
--- /dev/null
@@ -0,0 +1,53 @@
+-------------------------------------------------------------------------\r
+--\r
+-- Filename: math_pkg.vhd\r
+-- =========\r
+--\r
+-- Short Description:\r
+-- ==================\r
+--   Utility Package defining often used mathematical functions\r
+--\r
+-------------------------------------------------------------------------\r
+\r
+package math_pkg is\r
+  -- Calculates the logarithm dualis of the operand and rounds up\r
+  -- the result to the next integer value.\r
+  function log2c(constant value : in integer) return integer;\r
+  -- Returns the maximum of the two operands\r
+  function max(constant value1, value2 : in integer) return integer;\r
+  -- Returns the maximum of the three operands\r
+  function max(constant value1, value2, value3 : in integer) return integer;\r
+end math_pkg;\r
+\r
+package body math_pkg is\r
+  function log2c(constant value : in integer) return integer is\r
+    variable ret_value : integer;\r
+    variable cur_value : integer;\r
+  begin\r
+    ret_value := 0;\r
+    cur_value := 1;\r
+    \r
+    while cur_value < value loop\r
+      ret_value := ret_value + 1;\r
+      cur_value := cur_value * 2;\r
+    end loop;\r
+    return ret_value;\r
+  end function log2c;\r
+  \r
+  function max(constant value1, value2 : in integer) return integer is\r
+    variable ret_value : integer;\r
+  begin\r
+    if value1 > value2 then\r
+      ret_value := value1;\r
+    else\r
+      ret_value := value2;\r
+    end if;\r
+    return ret_value;\r
+  end function max;\r
+  \r
+  function max(constant value1, value2, value3 : in integer) return integer is\r
+  begin\r
+    return max(max(value1, value2), value3);\r
+  end function max;\r
+ end package body math_pkg;\r
\ No newline at end of file
diff --git a/debouncing/src/sync.vhd b/debouncing/src/sync.vhd
new file mode 100644 (file)
index 0000000..8515bd6
--- /dev/null
@@ -0,0 +1,17 @@
+library ieee;\r
+use ieee.std_logic_1164.all;\r
+\r
+entity sync is\r
+  generic\r
+  (\r
+    SYNC_STAGES : integer range 2 to integer'high;\r
+    RESET_VALUE : std_logic\r
+  );\r
+  port\r
+  (\r
+    sys_clk : in std_logic;\r
+    sys_res_n : in std_logic;\r
+    data_in : in std_logic;\r
+    data_out : out std_logic\r
+  );\r
+end entity sync;\r
diff --git a/debouncing/src/sync_beh.vhd b/debouncing/src/sync_beh.vhd
new file mode 100644 (file)
index 0000000..826bb12
--- /dev/null
@@ -0,0 +1,19 @@
+library ieee;\r
+use ieee.std_logic_1164.all;\r
+\r
+architecture beh of sync is\r
+  signal sync : std_logic_vector(1 to SYNC_STAGES);\r
+begin\r
+  process(sys_clk, sys_res_n)\r
+  begin\r
+    if sys_res_n = '0' then\r
+      sync <= (others => RESET_VALUE);\r
+    elsif rising_edge(sys_clk) then\r
+      sync(1) <= data_in;\r
+      for i in 2 to SYNC_STAGES loop\r
+        sync(i) <= sync(i - 1);\r
+      end loop;\r
+    end if;\r
+  end process;\r
+  data_out <= sync(SYNC_STAGES);\r
+end architecture beh;\r
diff --git a/debouncing/src/sync_pkg.vhd b/debouncing/src/sync_pkg.vhd
new file mode 100644 (file)
index 0000000..2b6247f
--- /dev/null
@@ -0,0 +1,19 @@
+library ieee;\r
+use ieee.std_logic_1164.all;\r
+\r
+package sync_pkg is\r
+  component sync is\r
+    generic\r
+    (\r
+      SYNC_STAGES : integer range 2 to integer'high;\r
+      RESET_VALUE : std_logic\r
+    );\r
+    port\r
+    (\r
+      sys_clk : in std_logic;\r
+      sys_res_n : in std_logic;\r
+      data_in : in std_logic;\r
+      data_out : out std_logic\r
+    );\r
+  end component sync;\r
+end package sync_pkg;
\ No newline at end of file