| 1 |
3 |
yannv |
----------------------------------------------------------------------------------
|
| 2 |
|
|
-- Company:
|
| 3 |
|
|
-- Engineer: Yann Vernier
|
| 4 |
|
|
--
|
| 5 |
|
|
-- Create Date: 23:05:04 09/08/2009
|
| 6 |
|
|
-- Design Name:
|
| 7 |
|
|
-- Module Name: debounce - Behavioral
|
| 8 |
|
|
-- Project Name:
|
| 9 |
|
|
-- Target Devices:
|
| 10 |
|
|
-- Tool versions:
|
| 11 |
|
|
-- Description: Debounces an input signal (for instance, a switch).
|
| 12 |
|
|
-- Output will only change after input has stayed one value between two enabled clock edges.
|
| 13 |
|
|
--
|
| 14 |
|
|
-- Dependencies:
|
| 15 |
|
|
--
|
| 16 |
|
|
-- Revision:
|
| 17 |
|
|
-- Revision 0.01 - File Created
|
| 18 |
|
|
-- Additional Comments:
|
| 19 |
|
|
--
|
| 20 |
|
|
----------------------------------------------------------------------------------
|
| 21 |
|
|
library IEEE;
|
| 22 |
|
|
use IEEE.STD_LOGIC_1164.ALL;
|
| 23 |
|
|
|
| 24 |
|
|
entity debounce is
|
| 25 |
|
|
Port ( clk : in STD_LOGIC;
|
| 26 |
|
|
clken : in STD_LOGIC;
|
| 27 |
|
|
input : in STD_LOGIC;
|
| 28 |
8 |
yannv |
output : out STD_LOGIC);
|
| 29 |
3 |
yannv |
end debounce;
|
| 30 |
|
|
|
| 31 |
|
|
-- Concept: input values are asynchronously connected to SR latches.
|
| 32 |
|
|
-- Those are synchronously reset, so if both are set, the input is unstable.
|
| 33 |
|
|
-- On Spartan 3 FPGAs, this architecture probably requires at least three slices,
|
| 34 |
|
|
-- due to separate RS lines for flip-flops. The output register may share, though.
|
| 35 |
|
|
architecture Behavioral of debounce is
|
| 36 |
|
|
-- 00->no input value observed (reset), 10 or 01 -> steady value, 11->value changed
|
| 37 |
|
|
signal inputv : std_logic_vector(0 to 1) := "00";
|
| 38 |
|
|
signal next_output : std_logic;
|
| 39 |
8 |
yannv |
signal current_output : std_logic;
|
| 40 |
3 |
yannv |
begin
|
| 41 |
8 |
yannv |
output <= current_output;
|
| 42 |
3 |
yannv |
-- our two asynch latches must agree for an update to occur
|
| 43 |
|
|
-- the tricky part of the code was convincing the synthesizer we only need one LUT3
|
| 44 |
|
|
-- to implement this consensus function (inputv must agree to alter output).
|
| 45 |
|
|
with inputv select
|
| 46 |
|
|
next_output <= '0' when "10",
|
| 47 |
|
|
'1' when "01",
|
| 48 |
8 |
yannv |
current_output when others;
|
| 49 |
3 |
yannv |
process (clk, input)
|
| 50 |
|
|
begin
|
| 51 |
|
|
-- input='0' for asynch set of input(0), synch reset
|
| 52 |
|
|
if input='0' then
|
| 53 |
|
|
inputv(0) <= '1';
|
| 54 |
|
|
elsif clken='1' and rising_edge(clk) then
|
| 55 |
|
|
inputv(0) <= '0';
|
| 56 |
|
|
end if;
|
| 57 |
|
|
-- same for 1
|
| 58 |
|
|
if input='1' then
|
| 59 |
|
|
inputv(1) <= '1';
|
| 60 |
|
|
elsif clken='1' and rising_edge(clk) then
|
| 61 |
|
|
inputv(1) <= '0';
|
| 62 |
|
|
end if;
|
| 63 |
|
|
-- finally, on enabled clocks, update output
|
| 64 |
|
|
if clken='1' and rising_edge(clk) then
|
| 65 |
8 |
yannv |
current_output <= next_output;
|
| 66 |
3 |
yannv |
end if;
|
| 67 |
|
|
end process;
|
| 68 |
|
|
end Behavioral;
|