首页IT科技状态机描述(基于状态机的按键消抖模块)

状态机描述(基于状态机的按键消抖模块)

时间2025-05-02 06:51:39分类IT科技浏览6908
导读:本次案例是按着小梅哥的思路来写的,部分截图和文字来自其教学视频。...

本次案例是按着小梅哥的思路来写的              ,部分截图和文字来自其教学视频              。

1              、状态机的设定

2                    、模块代码

`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer:Lclone // // Create Date: 2023/01/14 20:44:54 // Design Name: // Module Name: key_filter // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module key_filter( input Clk, //时钟信号 input Rst_n, //复位信号 input Key_in, //按键输入信号 output reg Key_press, //按键按下信号 output reg Key_release //按键释放信号 ); reg [1:0] key_reg; always @(posedge Clk or negedge Rst_n) begin if(Rst_n == 0) key_reg <= 0; else key_reg <= {key_reg[0],Key_in};//打拍子                    ,为了捕获上升沿和下降沿 end reg key_nedge; reg key_pedge; always @(posedge Clk or negedge Rst_n) begin if(Rst_n == 0) begin key_nedge <= 0; key_pedge <= 0; end else if(key_reg == 2b10 )//下降沿捕获 key_nedge <= 1b1; else if(key_reg == 2b01 )//上降沿捕获 key_pedge <= 1b1; else begin key_nedge <= 0; key_pedge <= 0; end end parameter CNT_20MS = 1_000_000; reg [19:0] cnt_20ms; reg [ 1:0] state; always @(posedge Clk or negedge Rst_n) begin if(Rst_n == 0) begin state <= 0; cnt_20ms <= 0; Key_press <= 0; Key_release <= 0; end else case(state) 0: begin Key_release <= 0; if(key_nedge == 1) state <= 1; else state <= 0; end 1: begin if(cnt_20ms < CNT_20MS & key_pedge == 1) begin state <= 0; cnt_20ms <= 0; end else if(cnt_20ms == CNT_20MS - 1) begin state <= 2; cnt_20ms <= 0; Key_press <= 1; end else cnt_20ms <= cnt_20ms + 1b1; end 2: begin Key_press <= 0; if(key_pedge == 1) state <= 3; else state <= 2; end 3: begin if(cnt_20ms < CNT_20MS & key_nedge == 1) begin state <= 2; cnt_20ms <= 0; end else if(cnt_20ms == CNT_20MS - 1) begin state <= 0; cnt_20ms <= 0; Key_release <= 1; end else cnt_20ms <= cnt_20ms + 1b1; end default:; endcase end endmodule

3      、仿真

(1)$random函数的使用

rand = {$random(seed)} % 10_000_000;

表示生成0-9_999_999范围内的随机数并赋值给rand; 1个seed数对应着1个的随机数      ,可以通过设定seed的值来复现该随机数; 可以去掉花括号后使生成的范围变成(-9_999_999) - 9_999_999;

(2)仿真代码

`timescale 1ns / 1ps module key_filter_tb(); reg clk_50m; initial clk_50m <= 1; always #10 clk_50m <= ~clk_50m; reg rst_n; initial begin rst_n <= 0; #200 rst_n <= 1; end reg key_in; wire key_press; wire key_release; key_filter key_filter_inst( .Clk (clk_50m), .Rst_n (rst_n), .Key_in (key_in), .Key_press (key_press), .Key_release (key_release) ); initial begin key_in <= 1; #400 press_key(1); #20 press_key(2); #20 press_key(3); end reg [31:0]rand; task press_key; input [3:0]seed; begin key_in = 1; #20_000_000; repeat(5)begin rand = {$random(seed)} % 10_000_000; #rand key_in = ~key_in; end key_in = 0; #40_000_000; repeat(5)begin rand = {$random(seed)} % 10_000_000; #rand key_in = ~key_in; end key_in = 1; #40_000_000; end endtask endmodule

(3)仿真结果

第一次按下

第二次按下

第三次按下

实验结果:每次按下都能准确发出Key_press和Key_release信号       ,实验初步验证成功                    。

4       、参考文献

[1]【零基础轻松学习FPGA】小梅哥Xilinx FPGA基础入门到项目应用培训教程】 https://www.bilibili.com/video/BV1va411c7Dz/?p=20&share_source=copy_web&vd_source=c6135c3b3a9878c08e2ddc91acdf6853&t=0

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
windows 10 修改用户名(win10修改用户名教程) 检查端口的命令是否正确(inncheck命令 – 检查语法)