1
0
mirror of https://github.com/aolofsson/oh.git synced 2025-01-30 02:32:53 +08:00
oh/common/hdl/oh_debouncer.v
2016-02-23 15:41:18 -05:00

69 lines
1.9 KiB
Verilog

//#########################################################################
//# Function: A digital debounce circuit
//# Usage: Set the BOUNCE and CLKPERIOD values during instantional to suite
//# your switch and clkperiod.
//#
//########################################################################
module oh_debouncer (/*AUTOARG*/
// Outputs
clean_out,
// Inputs
clk, nreset, noisy_in
);
// parameters (in milliseconds)
parameter BOUNCE = 100; // bounce time of switch (s)
parameter CLKPERIOD = 0.00001; // period (10ns=0.0001ms))
parameter CW = $clog2(BOUNCE/CLKPERIOD);// counter width needed
// signal interface
input clk; // clock to synchronize to
input nreset; // syncronous active high reset
input noisy_in; // noisy input signal to filter
output clean_out; // clean signal to logic
//temp variables
wire noisy_synced;
reg noisy_reg;
reg clean_out;
wire nreset_synced;
// synchronize reset
oh_dsync dsync (.dout (noisy_synced),
.clk (clk),
.din (noisy_in));
// synchronize input to clk (always!)
oh_rsync rsync (.nrst_out (nreset_synced),
.clk (clk),
.nrst_in (nreset));
// detecting change in state on input
always @ (posedge clk)
noisy_reg <= noisy_synced;
assign change_detected = noisy_reg ^ noisy_synced;
// synchronous counter
oh_counter #(.DW(CW))
oh_counter (// Outputs
.count (),
.carry (carry),
.zero (),
// Inputs
.clk (clk),
.in (1'b1),
.en (~carry), //done if you reach carry
.load (change_detected | ~nreset_synced),
.load_data ({(CW){1'b0}})
);
// sample noisy signal safely
always @ (posedge clk)
if(carry)
clean_out <= noisy_reg;
endmodule