118 lines
2.9 KiB
Verilog
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
|