如何做網(wǎng)站的的關(guān)鍵詞網(wǎng)絡(luò)培訓(xùn)學(xué)校
實(shí)現(xiàn)按鍵消抖功能:
1.濾除按鍵按下時的噪聲和松開時的噪聲信號。
2.獲取已消抖的按鍵按下的標(biāo)志信號。
3.實(shí)現(xiàn)已消抖的按鍵的連續(xù)功能。
Verilog實(shí)現(xiàn)
模塊端口
key_filter(input wire clk ,input wire rst_n ,input wire key_in , //按下按鍵時為0output reg key_flag, //第一次按下的標(biāo)志信號(已消抖)output reg key_out , //輸出按鍵信號(已消抖)output reg key_cont //輸出連續(xù)按鍵信號(已消抖)-計時一段時間拉高1次
);
20ms計數(shù)
always@(posedge clk or negedge rst_n)if(!rst_n) cnt_20ms <= 20'd0;else if(key_in) //松下按鍵cnt_20ms <= 20'd0;else if(cnt_20ms == CNT_20MS_MAX) //達(dá)到消抖時間cnt_20ms <= CNT_20MS_MAX;elsecnt_20ms <= cnt_20ms+20'd1;
按鍵第一次按下的標(biāo)志信號
always@(posedge clk or negedge rst_n)if(!rst_n) key_flag<=1'b0;else if(cnt_20ms == CNT_20MS_MAX-20'd1) //已消抖,拉高key_flag一個周期key_flag<= 1'b1;else key_flag<=1'b0;
已消抖的按鍵信號
always@(posedge clk or negedge rst_n)if(!rst_n) key_out<=1'b0;else if(key_in) //松下按鍵key_out<= 1'b0;else if(key_flag) //已消抖key_out<= 1'b1;else ;
連續(xù)信號所需計數(shù)器
always@(posedge clk or negedge rst_n)if(!rst_n) cnt_cont <= 20'd0;else if(key_out) begin //已消抖if(cnt_cont == CNT_CONT_MAX)cnt_cont <= 20'd0;else cnt_cont <= cnt_cont+20'd1;endelsecnt_cont <= 20'd0;
連續(xù)按鍵信號(已消抖)-計時一段時間拉高1次
always@(posedge clk or negedge rst_n)if(!rst_n) key_cont<=1'b0;else if(key_flag)key_cont <= 1'b1;else if(key_out) begin //已消抖if(cnt_cont == CNT_CONT_MAX) //連續(xù)按下一定時間,拉高key_cont一個周期key_cont <= 1'b1;else key_cont <= 1'b0;endelsekey_cont <= 1'b0;
testbench:
`timescale 1ns/1ns
module tb_key_filter();reg clk ;
reg rst_n ;
reg key_in ;
reg [7:0] tb_cnt ;wire key_flag;
wire key_out ;
wire key_cont;defparam u_key_filter.CNT_20MS_MAX = 20'd9;
defparam u_key_filter.CNT_CONT_MAX = 24'd49;initial begin clk = 1'b1 ;rst_n = 1'b0;#20rst_n = 1'b1;#(20*199+100)$stop;
endalways #10 clk=~clk;always@(posedge clk or negedge rst_n)if(!rst_n) tb_cnt <=8'b0;else if(tb_cnt ==8'd199)tb_cnt <=8'b0;elsetb_cnt <= tb_cnt +8'b1;always@(posedge clk or negedge rst_n)if(!rst_n) key_in <= 1'b1 ; else if(((tb_cnt>=8'd9) && (tb_cnt<=8'd39))||((tb_cnt>=8'd159) && (tb_cnt<=8'd179)))key_in<={$random}%2;else if((tb_cnt<8'd9)||(tb_cnt>8'd179))key_in<=1'b1;elsekey_in<=1'b0;key_filter u_key_filter(.clk (clk ),.rst_n (rst_n ),.key_in (key_in ), .key_flag (key_flag ), //第一次按下的標(biāo)志信號(已消抖).key_out (key_out ), //輸出按鍵信號(已消抖).key_cont (key_cont ) //輸出連續(xù)按鍵信號(已消抖)-計時一段時間拉高1次
);endmodule