ULX3Sでチャタリング除去回路(デバウンサ)
https://gyazo.com/8b2aa058be0cde515ac771e806415224
以下の回路のような「ボタンを押した時にカウントアップ」をしようとすると、ボタンのチャタリングにより一度に2増えたり3増えたりする。
code:top.v
module top(input clk_25mhz,
output wifi_gpio0);
wire i_clk;
// Tie GPIO0, keep board from rebooting
assign wifi_gpio0 = 1'b1;
// カウンタ
// カウンタの値をLEDへ出力
assign led = count;
// btn1 が押されたらカウントアップ
always @(posedge btn1) begin count <= count + 1;
end
endmodule
そういう時はボタンにチャタリング除去回路(デバウンサ)をかませてやる。
以下は、i_btn が10ミリ秒間押されたままの状態だったら o_btn に「ボタン押された」を出力するチャタリング除去回路(ボタンが離された場合も同様に10ミリ秒待つ必要がある)。wait_cycle はクロックの周波数と待ち時間(今回は10ミリ秒)に応じて適切に調整する必要がある。
code:btn_debouncer.v
module btn_debouncer(
input i_clk,
input i_btn,
output reg o_btn = 1'b0
);
// 25MHzのクロックで10ミリ秒待つのに必要なカウント = 250000
localparam wait_cycle = 250000;
reg btn_state = 0;
always @(posedge i_clk) begin
if (i_btn == btn_state && counter >= wait_cycle) begin
btn_state <= i_btn;
o_btn <= i_btn;
counter <= 0;
end else if (i_btn == btn_state && counter < wait_cycle) begin
counter <= counter + 1;
end else begin
btn_state <= i_btn;
counter <= 0;
end
end
endmodule
code:top.v
module top(
input clk_25mhz,
output wifi_gpio0
);
// Tie GPIO0, keep board from rebooting
assign wifi_gpio0 = 1'b1;
wire btn6;
assign led = count;
btn_debouncer btn6_debouncer(
.i_clk(clk_25mhz),
.o_btn(btn6)
);
// btn6 が押されたらカウントアップ
always @(posedge btn6) begin
count <= count + 1;
end
endmodule