pp.318-320
チャタリング除去回路1 / 安定期間がチャタリング想定期間よりも長く続いたらレベルを確定する -で試した回路をVHDLで書き換える。
この回路をそのままVHDLで表現する。ただしカウンターはパラメタライズする。
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use ieee.math_real.all; entity debouncer is generic( T_DEB_MS : natural := 25; -- バウンス継続想定ミリ秒数 F_CLK_KHZ : natural := 1000 ); port( x, clk: in std_logic; y : out std_logic ); end entity; architecture rtl of debouncer is -- バウンス継続想定時間は厳密である必要はないのでカウンターのモジュロは2**Nでよいが、 -- MSBをイネーブル信号として使いたいのでカウンターのビット数を1増やす。 constant COUNTER_BITS: natural := 1 + integer(ceil(log2(real(T_DEB_MS * F_CLK_KHZ)))); signal x_reg: std_logic; begin process(clk) variable count: unsigned(COUNTER_BITS-1 downto 0); -- この変数をカウンターとして使う。 begin if rising_edge(clk) then x_reg <= x; -- これが波形整形のための入力レジスタ。なくても、ほとんどの場合問題ない。 if y=x_reg then -- スイッチが確定状態にある限り、あるいは確定状態になくてもたまたま入出力が一致した場合は、 count := (others => '0'); -- 何度でもカウンターをリセットするが、 else count := count + 1; -- スイッチが変化したら(すなわち入出力が異なる場合は)カウントアップして、 end if; end if; if falling_edge(clk) then if count(COUNTER_BITS-1) then -- カウンターのMSBに1が立ったら(すなわち入出力の異なる状態がバウンス継続想定時間を超えたら)、 y <= not y; -- 出力をトグルする。 end if; end if; end process; end architecture;
黄が前回同様ATmega328Pで作った擬似チャタリング波形。緑がチャタリング除去後の波形。