-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathdebouncer.sv
125 lines (90 loc) · 5.67 KB
/
debouncer.sv
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/*===============================================================================================================================
Module : Debouncer
Description : Debouncer is used to filter bouncing found in typical switches and provide a clean, glitch-free state change.
-- Configurable bouncing interval in powers of 2 (threshold).
-- Changes state at the output based on counting the no. of times the same input is sampled consecutively.
Switch state transition appears at output only if the count crosses the threshold.
-- Debounces both assertion and release of switches.
-- Supports both pull-up and pull-down switch inputs.
-- Debouncer is designed to debounce switches with pull-down (OFF state = '0', ON state = '1').
For pull-up switches (OFF state = '1', ON state = '0'), debounced signal should be treated as valid
only after one bouncing interval latency after reset. Because on reset, debounced signal
drives '0' by default, which is ON state for pull-up switch. This may be undesirable.
If the initial latency is undesired, IS_PULLUP parameter can be set.
Developer : Mitu Raj, chip@chipmunklogic.com at Chipmunk Logic ™, https://chipmunklogic.com
Notes : Fully synthesisable, portable and tested code.
< 10 MHz clock is recommended for minimal resource usage assuming < 10 ms as switch bouncing time.
License : Open-source.
Date : Nov-09-2021
===============================================================================================================================*/
/*-------------------------------------------------------------------------------------------------------------------------------
D E B O U N C E R
-------------------------------------------------------------------------------------------------------------------------------*/
module debouncer #(
// Global Parameters
parameter N_BOUNCE = 3 , // Bouncing interval in clock cycles = 2^N_BOUNCE
parameter IS_PULLUP = 0 // Optional: '1' for pull-up switch, '0' for pull-down switch
)
(
input logic clk , // Clock
input logic rstn , // Active-low synchronous reset
input logic i_sig , // Bouncing signal from switch
output logic o_sig_debounced // Debounced signal
) ;
/*-------------------------------------------------------------------------------------------------------------------------------
Internal Registers/Signals
-------------------------------------------------------------------------------------------------------------------------------*/
logic isig_rg, isig_sync_rg ; // Registers in 2FF Synchronizer
logic sig_rg, sig_d_rg, sig_debounced_rg ; // Registers for switch's state
logic [N_BOUNCE : 0] counter_rg ; // Counter
logic [N_BOUNCE : 0] nxt_cnt ; // Next count
/*-------------------------------------------------------------------------------------------------------------------------------
Synchronous logic for debouncing
-------------------------------------------------------------------------------------------------------------------------------*/
always @(posedge clk) begin
// Reset
if (!rstn) begin
// Internal Registers
sig_rg <= IS_PULLUP ;
sig_d_rg <= IS_PULLUP ;
sig_debounced_rg <= IS_PULLUP ;
counter_rg <= 1 ;
end
// Out of reset
else begin
// Register state of switch
sig_rg <= isig_sync_rg ;
sig_d_rg <= sig_rg ;
// Increment counter if two consecutive states are same, otherwise reset
counter_rg <= (sig_d_rg == sig_rg) ? nxt_cnt : 1 ;
// Counter overflow, valid state registered
if (counter_rg [N_BOUNCE]) begin
sig_debounced_rg <= sig_d_rg ;
end
end
end
assign nxt_cnt = (counter_rg [N_BOUNCE])? counter_rg : (counter_rg + 1) ;
/*-------------------------------------------------------------------------------------------------------------------------------
2FF Synchronizer
-------------------------------------------------------------------------------------------------------------------------------*/
always @(posedge clk) begin
// Reset
if (!rstn) begin
// Internal Registers
isig_rg <= IS_PULLUP ;
isig_sync_rg <= IS_PULLUP ;
end
// Out of reset
else begin
isig_rg <= i_sig ; // Metastable flop
isig_sync_rg <= isig_rg ; // Synchronizing flop
end
end
/*-------------------------------------------------------------------------------------------------------------------------------
Continuous Assignments
-------------------------------------------------------------------------------------------------------------------------------*/
assign o_sig_debounced = sig_debounced_rg ;
endmodule
/*-------------------------------------------------------------------------------------------------------------------------------
D E B O U N C E R
-------------------------------------------------------------------------------------------------------------------------------*/