summaryrefslogtreecommitdiffstats
path: root/debounce.v
blob: 0fd49eaa105b95a42608229d690954b33e40a8d8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
module debounce (
		 clk,
		 reset_n,
		 in,
		 out,
		 strobe
		 );
   // This is optimized for a 25 MHz clock and the
   // assumption that glitches are limited to ~2 ms
   parameter ctrbits = 16;

   parameter width = 1;

   input  clk;
   input  reset_n;
   input  [width-1:0] in;
   output [width-1:0] out;
   output strobe;

   reg [width-1:0]   out;
   reg [width-1:0]   strobes;
   reg [ctrbits-1:0] ctr [0:width-1];

   assign strobe = |strobes;

   wire [width-1:0]  in_q;

   synchronize #(.width(width))
	debounce_sync (.reset(~reset_n), .clk(clk), .enable(1'b1),
		       .d(in), .q(in_q));

   genvar i;
   generate
	for (i = 0; i < width; i = i + 1)
	  begin: gen_debounce
	     always @(negedge reset_n or posedge clk)
	       if ( ~reset_n )
		 begin
		    out[i]     <= 1'b0;
		    strobes[i] <= 1'b0;
		    ctr[i]     <= {1'b0, {ctrbits-1{1'b0}}};
		 end
	       else
		 begin
		    strobes[i] <= 1'b0;

		    if ( in_q[i] )
		      begin
			 if ( &ctr[i] )
			   begin
			      out[i] <= 1'b1;
			      strobes[i] <= 1'b1;
			   end
			 else
			   ctr[i] <= ctr[i] + 1'b1;
		      end
		    else
		      begin
			 if ( ~|ctr[i] )
			   begin
			      out[i] <= 1'b0;
			      strobes[i] <= 1'b1;
			   end
			 else
			   ctr[i] <= ctr[i] - 1'b1;
		      end // else: !if( in[i] )
		 end // else: !if( ~reset_n )
	  end // block: gen_debounce
   endgenerate
endmodule // debounce