集成电路技术分享

 找回密码
 我要注册

QQ登录

只需一步,快速开始

搜索
12
返回列表 发新帖
楼主: lcytms

FPGA初级课程第六讲 单独按键消抖

[复制链接]
 楼主| lcytms 发表于 2016-11-4 17:24:13 | 显示全部楼层
本帖最后由 lcytms 于 2016-11-4 17:28 编辑

设计算是完成了。
我们再来进行一些扩展的思考。

有些时候,我们需要输出的是一个按键脉冲,表示按下了一次键。
而我们之前的程序仅仅是做了一个单纯的10ms滤波,也就是要求按键按下、释放均需经过10ms持续保持时间再确认。
我们对之前的程序稍微修改一下,就可以达到这个目的。
也就是在滤波结果的下降沿输出一个对应的脉冲即可,类似于flag标志信号,我们这里称之为key_flag,即按键标志信号。

我们新建一个key_flag.v文件。
module key_flag (clk, rst_n, key_n, key_out);

        input clk, rst_n;
        input key_n;
       
        output key_out;
       
        reg click_n;
       
        parameter MASK_TIME = 500_000;        // 10ms/20ns = 500_000, for checking key hold time
       
        reg [18:0] cnt;
        reg state;
       
        localparam        s0 = 1'b0,
                                        s1 = 1'b1;

        always @ (posedge clk or negedge rst_n)
                begin
                        if (!rst_n)
                                begin
                                        cnt <= 0;
                                        click_n <= 1;
                                        state <= s0;
                                end
                        else
                                begin
                                        case (state)
                                        s0        :        begin
                                                                if (key_n)
                                                                        begin
                                                                                cnt <= 0;
                                                                                click_n <= 1;
                                                                                state <= s0;
                                                                        end
                                                                else
                                                                        begin
                                                                                if (cnt < MASK_TIME - 1)
                                                                                        begin
                                                                                                cnt <= cnt + 19'b1;
                                                                                                state <= s0;
                                                                                        end
                                                                                else
                                                                                        begin
                                                                                                cnt <= 0;
                                                                                                click_n <= 0;
                                                                                                state <= s1;
                                                                                        end
                                                                        end
                                                        end
                                                       
                                        s1        :        begin
                                                                if (!key_n)
                                                                        begin
                                                                                cnt <= 0;
                                                                                click_n <= 0;
                                                                                state <= s1;
                                                                        end
                                                                else
                                                                        begin
                                                                                if (cnt < MASK_TIME - 1)
                                                                                        begin
                                                                                                cnt <= cnt + 19'b1;
                                                                                                state <= s1;
                                                                                        end
                                                                                else
                                                                                        begin
                                                                                                cnt <= 0;
                                                                                                click_n <= 1;
                                                                                                state <= s0;
                                                                                        end
                                                                        end
                                                        end
                                       
                                        default        :        state <= s0;
                                       
                                        endcase               
                                end
                end

        reg click_r_n;
       
        always @ (posedge clk or negedge rst_n)
                begin
                        if (!rst_n)
                                click_r_n <= 1;
                        else
                                click_r_n <= click_n;
                end
       
        assign key_out = click_r_n & ~click_n;
               
endmodule

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?我要注册

x
 楼主| lcytms 发表于 2016-11-4 17:29:58 | 显示全部楼层
本帖最后由 lcytms 于 2016-11-4 17:53 编辑

将key_flag.v模块设置为顶层模块,进行分析综合检查。
新建Testbench文件key_flag_tb.v。
`timescale 1ns/1ps

module key_flag_tb;

        reg clk, rst_n;
        reg key_n;
       
        wire key_out;

        key_flag #(.MASK_TIME(5))
                dut (.clk(clk), .rst_n(rst_n), .key_n(key_n), .key_out(key_out));

        initial
                begin
                        clk = 1;
                        rst_n = 0;
                        key_n = 1;
                        #200.1
                        rst_n = 1;
                       
                        #200
                        key_n = 0;
                        #10
                        key_n = 1;
                        #20
                        key_n = 0;
                        #80
                        key_n = 1;
                        #200
                        key_n = 0;
                        #400                        //key hold time is long enough
                        key_n = 1;
                        #10
                        key_n = 0;
                        #20
                        key_n = 1;
                        #80
                        key_n = 0;
                        #200
                        key_n = 1;
                        #200                        //key hold time is long enough
                       
                        #200 $stop;
                end
       
        always #10 clk = ~clk;

endmodule

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?我要注册

x
 楼主| lcytms 发表于 2016-11-4 17:55:03 | 显示全部楼层
设置好仿真。
仿真结果如下。
看到了key_out是一个脉冲,代表有一次按键按下。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?我要注册

x
 楼主| lcytms 发表于 2016-11-4 17:56:36 | 显示全部楼层
好了,今天的课程就讲到这里。
通过今天的课程,我们学习了单独按键消抖的基本原理,并对单独按键消抖电路进行了建模和仿真检查。
希望大家建立对单独按键消抖的理解,并熟练运用Verilog语言编写驱动逻辑。
更复杂的知识和技巧我们将逐步通过后面的课程展现给大家。

课程到此结束,谢谢大家的关注!
zxopen08 发表于 2016-11-9 13:50:19 | 显示全部楼层
FPGA初级课程第六讲 单独按键消抖
辉煌 发表于 2016-12-24 09:28:52 | 显示全部楼层
感谢群主分享
fpga_feixiang 发表于 2023-9-29 12:13:27 | 显示全部楼层
6                       
您需要登录后才可以回帖 登录 | 我要注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

QQ|小黑屋|手机版|Archiver|fpga论坛|fpga设计论坛 ( 京ICP备20003123号-1 )

GMT+8, 2024-12-23 20:20 , Processed in 0.059034 second(s), 17 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表