Files
BSI-901-fpga-software/c64_pro.srcs/sources_1/rtl/utils/debouncing.v
T
2024-10-28 13:14:49 +08:00

118 lines
2.9 KiB
Verilog

`timescale 1 ns / 1 ps
module debouncing#
(
parameter CLK_PERIOD = 10 ,
parameter DATA_WIDTH = 32 ,
parameter DELAY1_US = 30 ,
parameter DELAY2_US = 50
)
(
input clk ,
input rst_n ,
input [DATA_WIDTH-1:0] data_in ,
output [DATA_WIDTH-1:0] data_out
);
//*****************************************************************************
// localparam definition
//*****************************************************************************
localparam IDLE = 4'd0 ;
localparam DELAY1_ST = 4'd1 ;
localparam DELAY2_ST = 4'd2 ;
localparam DELAY_CNT_1 = (DELAY1_US*1000)/CLK_PERIOD;
localparam DELAY_CNT_2 = (DELAY2_US*1000)/CLK_PERIOD;
//*****************************************************************************
// Internal register and wire declarations
//*****************************************************************************
reg [ 4-1:0] state ;
reg [DATA_WIDTH-1:0] data_in_1b ;
reg [DATA_WIDTH-1:0] data_in_2b ;
reg [DATA_WIDTH-1:0] data_in_r ;
reg [DATA_WIDTH-1:0] data_in_rr ;
reg [ 16-1:0] cnt_1 ;
reg [ 16-1:0] cnt_2 ;
//*****************************************************************************
always @ ( posedge clk or negedge rst_n ) begin
if ( !rst_n ) begin
data_in_1b <= 0;
data_in_2b <= 0;
end else begin
data_in_1b <= data_in;
data_in_2b <= data_in_1b;
end
end
always @ ( posedge clk or negedge rst_n ) begin
if( !rst_n )
data_in_r <= 0;
else if (data_in_2b == data_in_1b)
data_in_r <= data_in_2b;
end
always @ ( posedge clk or negedge rst_n ) begin
if( !rst_n )
data_in_rr <= 0;
else if (cnt_2 == DELAY_CNT_2)
data_in_rr <= data_in_r;
end
always @ ( posedge clk or negedge rst_n ) begin
if( !rst_n )
state <= IDLE;
else begin
case (state)
IDLE:
if (data_in_rr != data_in_r)
state <= DELAY1_ST;
else
state <= IDLE;
DELAY1_ST:
if (cnt_1 == DELAY_CNT_1) begin
if (data_in_rr != data_in_r)
state <= DELAY2_ST;
else
state <= IDLE;
end else
state <= DELAY1_ST;
DELAY2_ST:
if (data_in_rr == data_in_r || cnt_2 == DELAY_CNT_2)
state <= IDLE;
else
state <= DELAY2_ST;
default:
state <= IDLE;
endcase
end
end
always @ ( posedge clk or negedge rst_n ) begin
if( !rst_n )
cnt_1 <= 0;
else if (state == DELAY1_ST)
cnt_1 <= cnt_1 + 1'b1;
else
cnt_1 <= 0;
end
always @ ( posedge clk or negedge rst_n ) begin
if( !rst_n )
cnt_2 <= 0;
else if (state == DELAY2_ST)
cnt_2 <= cnt_2 + 1'b1;
else
cnt_2 <= 0;
end
//*****************************************************************************
// Wire assignment
//*****************************************************************************
assign data_out = data_in_rr;
endmodule