65 lines
1.2 KiB
Systemverilog
65 lines
1.2 KiB
Systemverilog
|
`timescale 1ns / 1ps `default_nettype none
|
||
|
|
||
|
module debounce (
|
||
|
input wire logic clk,
|
||
|
reset,
|
||
|
noisy,
|
||
|
output logic debounced
|
||
|
);
|
||
|
|
||
|
logic timerDone, clrTimer;
|
||
|
|
||
|
typedef enum logic [1:0] {
|
||
|
s0,
|
||
|
s1,
|
||
|
s2,
|
||
|
s3,
|
||
|
ERR = 'X
|
||
|
} state_type_e;
|
||
|
state_type_e ns, cs;
|
||
|
|
||
|
logic [18:0] tA;
|
||
|
|
||
|
timer #(.MOD_VALUE(500000), .BIT_WIDTH(19)) T0 (
|
||
|
.clk(clk),
|
||
|
.reset(clrTimer),
|
||
|
.increment(1'b1),
|
||
|
.rolling_over(timerDone),
|
||
|
.count(tA)
|
||
|
);
|
||
|
|
||
|
always_comb begin
|
||
|
ns = ERR;
|
||
|
clrTimer = 0;
|
||
|
debounced = 0;
|
||
|
|
||
|
if (reset) ns = s0;
|
||
|
else
|
||
|
case (cs)
|
||
|
s0: begin
|
||
|
clrTimer = 1'b1;
|
||
|
if (noisy) ns = s1;
|
||
|
else ns = s0;
|
||
|
end
|
||
|
s1:
|
||
|
if (noisy && timerDone) ns = s2;
|
||
|
else if (noisy && ~timerDone) ns = s1;
|
||
|
else ns = s0;
|
||
|
s2: begin
|
||
|
debounced = 1'b1;
|
||
|
clrTimer = 1'b1;
|
||
|
if (noisy) ns = s2;
|
||
|
else ns = s3;
|
||
|
end
|
||
|
s3: begin
|
||
|
debounced = 1'b1;
|
||
|
if (~noisy && timerDone) ns = s0;
|
||
|
else if (~noisy && ~timerDone) ns = s3;
|
||
|
else ns = s2;
|
||
|
end
|
||
|
endcase
|
||
|
end
|
||
|
|
||
|
always_ff @(posedge clk) cs <= ns;
|
||
|
endmodule
|