`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