-
Notifications
You must be signed in to change notification settings - Fork 0
/
debouncer.v
84 lines (77 loc) · 2.06 KB
/
debouncer.v
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
`default_nettype none
`timescale 1ns/1ps
// debouncer #(
// NOISE_PERIOD (),
// RESET_VALUE ()
// ) (
// .clock (),
// .reset (),
// .enable (),
// .data_i (),
// .data_o ()
// );
module debouncer #(
parameter integer NOISE_PERIOD = 256,
parameter RESET_VALUE = 0
) (
input wire clock,
input wire reset,
input wire enable,
input wire data_i,
output wire data_o
);
localparam C_STATE_BITS = 1;
localparam STATE_IDLE = 0;
localparam STATE_CHANGING = 1;
wire state;
wire rollover;
reg next_state;
always @(*) begin
if (state == STATE_CHANGING) begin
if (rollover || data == data_i) begin
next_state = STATE_IDLE;
end else begin
next_state = state;
end
end else begin
if (data != data_i) begin
next_state = STATE_CHANGING;
end else begin
next_state = state;
end
end
end
wire counter_reset = (state == STATE_IDLE);
wire counter_enable = (state == STATE_CHANGING);
wire data_write_enable = (state == STATE_CHANGING && next_state == STATE_IDLE);
register #(
.RESET_VALUE (STATE_IDLE),
.WIDTH (C_STATE_BITS)
) state_register_inst (
.clock (clock),
.reset (reset),
.write_enable (enable),
.data_i (next_state),
.data_o (state)
);
counter #(
.HIGH (NOISE_PERIOD-1)
) counter_inst (
.clock (clock),
.clock_enable (enable),
.sync_reset (reset || counter_reset),
.enable (counter_enable),
.count (),
.tc (rollover)
);
register #(
.RESET_VALUE (RESET_VALUE),
.WIDTH (1)
) data_register_inst (
.clock (clock),
.reset (reset),
.write_enable (enable && data_write_enable),
.data_i (data_i),
.data_o (data_o)
);
endmodule