module key_filter
#(
parameter MAX_CNT_20MS = 20'd100_0000
)(
input wire sys_clk ,
input wire sys_rst_n ,
input wire key_in ,
output reg key_out
);
reg key_r_0 ;
reg key_r_1 ;
wire nege ;
wire pose ;
reg [19:00] cnt_20ms ;
wire add_cnt_20ms ;
wire end_cnt_20ms ;
reg add_cnt_flag ;
// key_r_0 key_r_1
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
key_r_0 <= 1'b1 ;
end else begin
key_r_0 <= key_in ;
end
end
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
key_r_1 <= 1'b1 ;
end else begin
key_r_1 <= key_r_0 ;
end
end
// nege pose
assign nege = ~key_r_0 && key_r_1 ;
assign pose = key_r_0 && ~key_r_1 ;
// add_cnt_flag
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
add_cnt_flag <= 1'b0 ;
end else begin
if(nege) begin
add_cnt_flag <= 1'b1 ;
end else begin
if( pose || end_cnt_20ms ) begin
add_cnt_flag <= 1'b0 ;
end else begin
add_cnt_flag <= add_cnt_flag ;
end
end
end
end
// cnt_20ms add_cnt_20ms end_cnt_20ms
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
cnt_20ms <= 20'd0 ;
end else begin
if(add_cnt_20ms) begin
if(end_cnt_20ms) begin
cnt_20ms <= 20'd0 ;
end else begin
cnt_20ms <= cnt_20ms + 20'd1 ;
end
end else begin
cnt_20ms <= 20'd0 ;
end
end
end
assign add_cnt_20ms = add_cnt_flag ;
assign end_cnt_20ms = add_cnt_20ms && cnt_20ms == ( MAX_CNT_20MS - 1'b1 ) ;
// key_out
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
key_out <= 1'b0 ;
end else begin
if(end_cnt_20ms) begin
key_out <= 1'b1 ;
end else begin
key_out <= 1'b0 ;
end
end
end
endmodule
`timescale 1ns/1ns
module test();
reg sys_clk ;
reg sys_rst_n ;
reg key_in ;
reg [07:00] cnt_tb ;
wire key_out ;
key_filter
#(
.MAX_CNT_20MS (50)
)
key_filter_insert
(
.sys_clk ( sys_clk ),
.sys_rst_n ( sys_rst_n ),
.key_in ( key_in ),
.key_out ( key_out )
);
parameter CYCLE = 20 ;
initial begin
sys_clk = 1'b1 ;
sys_rst_n <= 1'b0 ;
#( CYCLE * 2 ) ;
sys_rst_n <= 1'b1 ;
#( 210 ) ;
sys_rst_n <= 1'b0 ;
#( CYCLE * 10 ) ;
sys_rst_n <= 1'b1 ;
#( CYCLE * 1000 ) ;
$stop ;
end
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
cnt_tb <= 0 ;
end else begin
if(cnt_tb == 249) begin
cnt_tb <= 0 ;
end else begin
cnt_tb <= cnt_tb + 1'b1 ;
end
end
end
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
key_in <= 1'b1 ;
end else begin
if(( 0 <= cnt_tb && cnt_tb <= 19 )||( 220 <= cnt_tb && cnt_tb <= 249 )) begin
key_in <= 1'b1 ;
end else begin
if(( 20 <= cnt_tb && cnt_tb <= 69 )||( 170 <= cnt_tb && cnt_tb <= 219 ) ) begin
key_in <= ($random) % 2 ;
end else begin
if(70 <= cnt_tb && cnt_tb <= 169) begin
key_in <= 1'b0 ;
end else begin
key_in <= key_in ;
end
end
end
end
end
always #( CYCLE / 2 ) sys_clk = ~sys_clk ;
endmodule